using DevExpress.XtraEditors; using HslCommunication.Profinet.Omron; using MQTTnet.Client; using SqlSugar; using System; using System.Collections.Generic; using System.Configuration; using System.Diagnostics; using System.Reflection; using System.Runtime.InteropServices; using System.Threading; using System.Windows.Forms; using ZJ_BYD.DB; using ZJ_BYD.Model; using ZJ_BYD.Untils; using ZJ_BYD.ViewModel; namespace ZJ_BYD { 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() { try { //设置应用程序处理异常方式:ThreadException处理 Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); //主线程异常捕获 Application.ThreadException += Application_ThreadException; //子线程异常捕获 AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); WindowsFormsSettings.UseAdvancedTextEdit = DevExpress.Utils.DefaultBoolean.True;//添加这一行MemoEdit设置字体颜色的事件才会触发 LogHelper.SetConfig(); DBHelper.GetConnStr(); //控件激活 var controlAuthor = HslControls.Authorization.SetAuthorizationCode("75a6294c-7cda-451d-a8b3-d8e54b5debf1"); if (!controlAuthor) { LogHelper.WriteLog("控件授权到期"); } //注册 var communicationAuthor = HslCommunication.Authorization.SetAuthorizationCode("f562cc4c-4772-4b32-bdcd-f3e122c534e3"); if (!communicationAuthor) { LogHelper.WriteLog("通讯授权到期"); XtraMessageBox.Show("通讯授权到期"); } LoadAppConfig(); GetCurrentConfig(); #region 加载当前工控机的有效工位 stationInfos = MskCodeHelper.QueryUsingMaChineTypeVM().OrderBy(a => a.SortIndex).ToList(); Program.PointKeyValues = PlcPointHelper.QueryActivePlcPoints().Where(m => m.IsActive) .Where(m => m.IpcId == Program.CurrentIpcId) .Select(m => new PointKeyValue { StationCode = m.StationCode, Key = m.PointCode, FieldCode = m.ResultField, KeyDesc = m.PointName, Address = m.PointStartAddress, Length = m.PointLength, DataType = m.PointDataType, IsShowMain = m.IsShowMain, IsSub = m.IsSub, IsTestItem = m.IsTestItem, IsResponseData = m.IsResponseData, IsSaveDb = m.IsSaveDb, SortIndex = m.SortIndex }).ToList(); #endregion t_MaskCodes = MskCodeHelper.QueryMskCodes().ToList(); #region 获取连接PLC对象 var connectPLC = new ConnectPLC(); Program.omronCipNet = connectPLC.GetOmronCipNet(); #endregion #region 定时任务 _ = QuartzHelper.Start(); #endregion #region 调用Win32 API,禁止程序重复运行并激活运行程序的窗口显示在最前端 /* * 这种方式在VS调用的情况不成立的,因为在VS中按F5运行的进程为OnlyInstanceRunning.vshost,从这个进程的命名就可以看出 该进程为OnlyInstanceRunning进程的宿主进程 而直接点OnlyInstanceRunning.exe运行的程序进程为OnlyInstanceRunning, 但是我们可以一些小的修改,即currentProcess.ProcessName.Replace(".vshose","")此时无论如何都为 OnlyInstanceRunning */ //获得正在运行的程序,如果没有相同的程序,则运行该程序 Process process = RunningInstance(); if (process == null) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new StartForm()); Application.Run(new LoginFrom()); } else { // 已经运行该程序,显示信息并使程序显示在前端 MessageBox.Show("应用程序已经在运行中......"); Thread.Sleep(1000); Environment.Exit(1); HandleRunningInstance(process); } #endregion } catch (Exception ex) { MessageBox.Show(ex.ToString()); } } private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { Exception ex = e.ExceptionObject as Exception; LogHelper.WriteErrorLog(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.WriteErrorLog(string.Format("捕获到未处理异常:{0}\r\n异常信息:{1}\r\n异常堆栈:{2}", ex.GetType(), ex.Message, ex.StackTrace)); } /// /// 读取基础配置信息 /// static void GetCurrentConfig() { var configInfo = CurrentConfigHelper.QueryCurrentConfigs() .Where(m => m.IpcId == Program.CurrentIpcId && m.LineCode == Program.CurrentLineCode) .First(); if (configInfo != null) { Program.LineName = configInfo.LineName; Program.MesIpAddress = configInfo.MesIp; Program.MesPort = configInfo.MesPort; Program.PlcIpAddress = configInfo.PlcIp; Program.PlcPort = string.IsNullOrWhiteSpace(configInfo.PlcPort) ? 44818 : int.Parse(configInfo.PlcPort); Program.MenuPwd = configInfo.MenuPwd; Program.HightPwd = configInfo.HightPwd; Program.areacode = configInfo.AreaCode; Program.deptcode = configInfo.DeptCode; } } /// /// 获取正在运行的程序,没有运行的程序则返回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); } #region 全局变量 /// /// 数据库类型 /// //public static DbType CurrentDbType = DbType.MySql; public static DbType CurrentDbType = DbType.PostgreSQL; public static IMqttClient mqttClient; //MQTT客户端实例 /// /// 地域代码 /// public static string areacode { get; set; } /// /// 工厂代码 /// public static string deptcode { get; set; } /// /// 读取PLC的频率 /// public static int readplcrate = 1000; /// /// PLC通讯状态 /// public static string communicationstatus { get; set; } /// /// 当前工控机标识 /// public static string CurrentIpcId { get; set; } /// /// 当前产线编码 /// public static string CurrentLineCode { get; set; } /// /// 激活中的工位编码 /// public static string ActiveStatinCode { get; set; } /// /// PLC连接对象 /// public static OmronCipNet omronCipNet = null; /// /// 测试文件名称 /// public static string testfilename { get; set; } /// /// 程序版本 /// public static string programversion { get; set; } /// /// PLC IP地址 /// public static string PlcIpAddress { get; set; } /// /// PLC端口 /// public static int PlcPort = 44818; /// /// MES IP地址 /// public static string MesIpAddress { get; set; } /// /// MES端口 /// public static string MesPort { get; set; } /// /// 菜单权限口令 /// public static string MenuPwd { get; set; } /// /// 最高权限口令 /// public static string HightPwd { get; set; } /// /// 系统模式 /// 0:离线 /// 1:在线 /// public static bool SysMode { get; set; } /// /// 产线名称 /// public static string LineName { get; set; } /// /// 软件版本号校验长度 /// public static int SoftVersionLen = 17; /// /// 标签码 /// public static string PrintBarCode { get; set; } /// /// 标签码的流水号 /// public static string SerialNum { get; set; } public static List stationInfos { get; set; } /// /// 掩码表集合 /// public static List t_MaskCodes { get; set; } /// /// 存储各工位读取PLC的返回值 /// public static List PointKeyValues { get; set; } /// /// mes请求超时时间 /// public static int MesPostTimeout { get; set; } = 15000; /// /// 机型 /// public static string MachineType { get; set; } /// /// 转子充磁工位编号 /// public static string ZZCC_ST { get; set; } /// /// 转子工序 /// public static string ZZCC_Procedure { get; set; } /// /// 是否查询动静盘支线 /// public static bool SearchDongJingPanBranch = true; /// /// 动静盘站号 /// public static string DongJingPanST { get; set; } /// /// 静盘工序 /// public static string JingPanProcedure { get; set; } /// /// 静盘参数 /// public static string JingPan_Param { get; set; } /// /// 静盘线 /// public static string[] JingPanLines { get; set; } /// /// 动盘工序 /// public static string DongPanProcedure { get; set; } /// /// 动盘线 /// public static string[] DongPanLines { get; set; } /// /// 动盘参数 /// public static string DongPan_Param { get; set; } /// /// 动静盘差值 /// public static List DongJingDvalue { get; set; } /// /// 补油(B90) /// public static string YZCS_ST { get; set; } #region 存数据库时使用 public static Type type = null; public static PropertyInfo[] properties = null; #endregion #region 人脸识别系统 /// /// 是否启用人脸识别系统 /// public static bool IsUseFace = false; public static string DeviceIp { get; set; } public static string DeviceUserName { get; set; } public static string DevicePwd { get; set; } public static ushort DevicePort = 8000; #endregion #endregion /// /// 加载App.config配置文件 /// static void LoadAppConfig() { CurrentIpcId = ConfigurationManager.AppSettings["ipccode"]; CurrentLineCode = ConfigurationManager.AppSettings["lincode"]; testfilename = ConfigurationManager.AppSettings["testfilename"]; programversion = ConfigurationManager.AppSettings["programversion"]; int.TryParse(ConfigurationManager.AppSettings["readplcrate"], out readplcrate); MesPostTimeout = int.Parse(ConfigurationManager.AppSettings["MesPostTimeout"]); ZZCC_ST = ConfigurationManager.AppSettings["ZZCC_ST"]; ZZCC_Procedure = ConfigurationManager.AppSettings["ZZCC_Procedure"]; DongJingPanST = ConfigurationManager.AppSettings["DongJingPanST"]; JingPanProcedure = ConfigurationManager.AppSettings["JingPanProcedure"]; JingPanLines = ConfigurationManager.AppSettings["JingPanLines"]?.Split(','); JingPan_Param = ConfigurationManager.AppSettings["JingPan_Param"]; DongPanProcedure = ConfigurationManager.AppSettings["DongPanProcedure"]; DongPanLines = ConfigurationManager.AppSettings["DongPanLines"]?.Split(','); DongPan_Param = ConfigurationManager.AppSettings["DongPan_Param"]; DongJingDvalue = new List(); var strDongJing = ConfigurationManager.AppSettings["DongJingDvalue"]; if (!string.IsNullOrWhiteSpace(strDongJing)) { string[] dvalue = strDongJing.Split('-'); if (dvalue.Length > 0) { foreach (string s in dvalue) { DongJingDvalue.Add(float.Parse(s)); } } } YZCS_ST = ConfigurationManager.AppSettings["YZCS_ST"]; var strSearchDongJingPanBranch = ConfigurationManager.AppSettings["SearchDongJingPanBranch"]; bool.TryParse(strSearchDongJingPanBranch, out SearchDongJingPanBranch); #region 人脸识别系统 DeviceIp = ConfigurationManager.AppSettings["DeviceIp"]; DeviceUserName = ConfigurationManager.AppSettings["DeviceUserName"]; DevicePwd = ConfigurationManager.AppSettings["DevicePwd"]; var strDevicePort = ConfigurationManager.AppSettings["DevicePort"]; ushort.TryParse(strDevicePort, out DevicePort); var strIsUseFace = ConfigurationManager.AppSettings["IsUseFace"]; bool.TryParse(strIsUseFace, out IsUseFace); #endregion } } }