using Common.HslAuthor.Framework; using CompressorXN.Untils; using CompressorXN_Common; using CompressorXN_Communication.TuMos; using CompressorXN_Log; using CompressorXN_Service; using Custom.Utils.Framework; using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.InteropServices; using System.Threading; using System.Windows.Forms; namespace CompressorXN { internal static class Program { #region 使用的Win32函数的声明 /// /// 设置窗口的显示状态 /// /// 窗口句柄 /// 指示窗口如何被显示 /// 如果窗体之前是可见,返回值为非零;如果窗体之前被隐藏,返回值为零 [DllImport("User32.dll")] private static extern bool ShowWindow(IntPtr hWnd, int cmdShow); /// /// 创建指定窗口的线程设置到前台,并且激活该窗口。键盘输入转向该窗口,并为用户改变各种可视的记号。 /// 系统给创建前台窗口的线程分配的权限稍高于其他线程。 /// /// 将被激活并被调入前台的窗口句柄 /// 如果窗口设入了前台,返回值为非零;如果窗口未被设入前台,返回值为零 [DllImport("User32.dll")] private static extern bool SetForegroundWindow(IntPtr hWnd); // 指示窗口为普通显示 private const int WS_SHOWNORMAL = 1; #endregion /// /// 应用程序的主入口点。 /// [STAThread] static void Main() { //设置应用程序处理异常方式:ThreadException处理 Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); //主线程异常捕获 Application.ThreadException += Application_ThreadException; //子线程异常捕获 AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); #region 调用Win32 API,禁止程序重复运行并激活运行程序的窗口显示在最前端 /* * 这种方式在VS调用的情况不成立的,因为在VS中按F5运行的进程为OnlyInstanceRunning.vshost,从这个进程的命名就可以看出 该进程为OnlyInstanceRunning进程的宿主进程 而直接点OnlyInstanceRunning.exe运行的程序进程为OnlyInstanceRunning, 但是我们可以一些小的修改,即currentProcess.ProcessName.Replace(".vshose","")此时无论如何都为 OnlyInstanceRunning */ //获得正在运行的程序,如果没有相同的程序,则运行该程序 Process process = RunningInstance(); if (process == null) { #region 授权 var communicationAuthor = HslAuthorize.HslCommunicationAuthor(); if (!communicationAuthor) { new FrmDialog("通讯授权失败!").ShowDialog(); } var hslControlAuthor = HslAuthorize.HslControlsAuthor(); if (!hslControlAuthor) { new FrmDialog("控件授权失败!").ShowDialog(); } #endregion InitSystemConfigIni();//读取配置文件 //FrmLogin frmLogin = new FrmLogin(); //frmLogin.ShowDialog(); //if (frmLogin.DialogResult == DialogResult.OK) //{ // Application.Run(new FrmMain()); //} Application.Run(new FrmMain()); } else { // 已经运行该程序,显示信息并使程序显示在前端 new FrmDialog("应用程序已经在运行中......").ShowDialog(); Thread.Sleep(1000); Environment.Exit(Environment.ExitCode); HandleRunningInstance(process); } #endregion } #region 异常捕获 private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { Exception ex = e.ExceptionObject as Exception; LogHelper.Error(ex, "子线程异常捕获", string.Format("捕获到未处理异常:{0}\r\n异常信息:{1}\r\n异常堆栈:{2}\r\nCLR即将退出:{3}", ex.GetType(), ex.Message, ex.StackTrace, e.IsTerminating)); } private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e) { Exception ex = e.Exception; LogHelper.Error(ex, "主线程异常捕获", string.Format("捕获到未处理异常:{0}\r\n异常信息:{1}\r\n异常堆栈:{2}", ex.GetType(), ex.Message, ex.StackTrace)); } #endregion #region 禁止程序重复运行相关 /// /// 获取正在运行的程序,没有运行的程序则返回null /// /// private static Process RunningInstance() { // 获取当前活动的进程 Process currentProcess = Process.GetCurrentProcess(); // 根据当前进程的进程名获得进程集合 // 如果该程序运行,进程的数量大于1 Process[] processcollection = Process.GetProcessesByName(currentProcess.ProcessName.Replace(".vshost", "")); foreach (Process process in processcollection) { // 如果进程ID不等于当前运行进程的ID以及运行进程的文件路径等于当前进程的文件路径 // 则说明同一个该程序已经运行了,此时将返回已经运行的进程 if (process.Id != currentProcess.Id) { if (Assembly.GetExecutingAssembly().Location.Replace("/", "\\") == process.MainModule.FileName) { return process; } } } return null; } /// /// 显示已运行的程序 /// /// private static void HandleRunningInstance(Process instance) { // 显示窗口 ShowWindow(instance.MainWindowHandle, WS_SHOWNORMAL); // 把窗体放在前端 SetForegroundWindow(instance.MainWindowHandle); } #endregion /// /// 读取系统INI配置文件 /// static void InitSystemConfigIni() { var iniFilePath = GlobalVar.IniFilePath; GlobalVar.PlcIpAddress=IniHelper.Read("PlcConfig", "Ip", string.Empty,iniFilePath); string strPlcPort = IniHelper.Read("PlcConfig", "port", string.Empty, iniFilePath); int.TryParse(strPlcPort, out int plcPort); GlobalVar.PlcPort = plcPort; var dbServerIp = IniHelper.Read("DdataBaseConfig", "DbServerIp", "127.0.0.1", iniFilePath); var port = IniHelper.Read("DdataBaseConfig", "Port", "5432", iniFilePath); var database = IniHelper.Read("DdataBaseConfig", "Database", "", iniFilePath); var userId = IniHelper.Read("DdataBaseConfig", "UserId", "postgres", iniFilePath); var password = IniHelper.Read("DdataBaseConfig", "Password", "", iniFilePath); var schema = IniHelper.Read("DdataBaseConfig", "Schema", "public", iniFilePath); var strIsEncrypt = IniHelper.Read("DdataBaseConfig", "DbPwdIsEncrypt", "false", iniFilePath); _ = bool.TryParse(strIsEncrypt, out bool isEncrypt); //数据库连接 DbContext.GetConStr(dbServerIp, port, database, userId, password, isEncrypt, schema); } } }