| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396 |
- using IWshRuntimeLibrary;
- using Microsoft.Win32;
- using SWRIS.Core;
- using SWRIS.Extensions;
- using SWRIS.Models;
- using SWRIS.Properties;
- using SWRIS.Services;
- using System;
- using System.Diagnostics;
- using System.IO;
- using System.Linq;
- using System.Reflection;
- using System.Threading.Tasks;
- using System.Web.Http;
- using System.Web.Http.SelfHost;
- using System.Windows;
- using System.Windows.Threading;
- namespace SWRIS
- {
- /// <summary>
- /// App.xaml 的交互逻辑
- /// </summary>
- public partial class App : Application
- {
- public static ConfigModel Config { get; set; }
- public static TcpServerFrame TcpServer { get; set; }
- public static CalibrationCore Calibration { get; set; }
- public static DataCenterModel DataCenter { get; set; }
- public static HistoryCleanupService HistoryCleanup { get; set; }
- private static string _processName = "SWRIS";
- private static string _appName = "在线式钢丝绳电磁检测系统";
- public App()
- {
- //首先注册开始和退出事件
- if (!Settings.Default.IsDebug)
- {
- Startup += new StartupEventHandler(App_Startup);
- if (!HslCommunication.Authorization.SetAuthorizationCode("946778b1-967c-4e05-beab-7f47bb248b71"))
- {
- LogHelper.Info("HSL授权失败");
- return;
- }
- }
- _processName = Assembly.GetEntryAssembly()?.GetName().Name ?? _processName;
- //PDF初始化配置
- QuestPDF.Settings.License = QuestPDF.Infrastructure.LicenseType.Community;
- QuestPDF.Settings.CheckIfAllTextGlyphsAreAvailable = false;
- }
- [Obfuscation(Feature = "virtualization", Exclude = false)]
- private void InitSoftAuthorize()
- {
- if (!SoftAuth.IsAuthorizeSuccess())
- {
- SoftAuthDialog authDialog = new SoftAuthDialog();
- var result = authDialog.ShowDialog();
- if (result != true)
- {
- Environment.Exit(0);
- }
- }
- }
- private static SingleInstanceManager _singleInstanceManager;
- public static void SwitchToExistingInstance(string processName)
- {
- _singleInstanceManager?.SwitchToExistingInstance(processName);
- }
- [Obfuscation(Feature = "virtualization", Exclude = false)]
- protected override void OnStartup(StartupEventArgs e)
- {
- #region 阻止系统睡眠,阻止屏幕关闭。
- SystemSleep.PreventForCurrentThread();
- #endregion
- #region 避免程序多次启动
- _singleInstanceManager = new SingleInstanceManager(_processName);
- // 检查是否已有实例运行
- if (_singleInstanceManager.IsAlreadyRunning())
- {
- // 切换到已有实例
- _singleInstanceManager.SwitchToExistingInstance();
- Shutdown();
- return;
- }
- #endregion
- Config = ConfigHelper.Read();
- if (Config == null)
- {
- LogHelper.Error("读取配置文件失败");
- Environment.Exit(0);
- }
- if (!Config.AppName.IsNullOrEmptyOrWhiteSpace())
- {
- _appName = Config.AppName;
- }
- if (Settings.Default.IsDebug)
- {
- SetAutoStartByStartupFolder(false);
- }
- else
- {
- //InitSoftAuthorize();
- //SetAutoStartByStartupFolder(true);
- // 创建桌面快捷方式
- CreateShortcut(Assembly.GetExecutingAssembly().Location, _appName);
- }
- // 显示启动画面
- var splashScreen = new SplashScreen("Resources/loading.png");
- splashScreen.Show(false, true);
- Task.Run(async () =>
- {
- SqLiteBaseRepository.CreateDatabase();
- //初始化TcpServer
- TcpServer = new TcpServerFrame(Config.IpAddress, Config.Port);
- //初始化标定模块
- Calibration = new CalibrationCore(Config.Calibration);
- //初始化数据中心能模块
- DataCenter = new DataCenterModel(Config.Equipments, Config.Calibration.Limits);
- //初始化清理计划模块
- HistoryCleanup = new HistoryCleanupService();
- HistoryCleanup.StartScheduledCleanup();
- // 数据加载完成后,在UI线程更新
- await Current.Dispatcher.InvokeAsync(() =>
- {
- splashScreen.Close(TimeSpan.FromMilliseconds(200));
- var mainWindow = new MainWindow
- {
- Height = SystemParameters.PrimaryScreenHeight,
- Width = SystemParameters.PrimaryScreenWidth
- };
- mainWindow.Activate();
- mainWindow.Show();
- });
- });
- base.OnStartup(e);
- }
- public static bool UpdateEquipment(EquipmentModel equipment)
- {
- if (equipment == null) return false;
- var existingEquipment = Config.Equipments.FirstOrDefault(e => e.RopeNumber == equipment.RopeNumber);
- if (existingEquipment == null) return false;
- // 更新设备信息
- Mapping.AssignFrom(existingEquipment, equipment);
- return true;
- }
- private void StartHttpServer()
- {
- //添加防火墙8002端口允许出站规则
- FirewallHelper.CreateTCPOutRule(Assembly.GetEntryAssembly().Location, remotePorts: "8002");
- var config = new HttpSelfHostConfiguration($"http://{Tools.GetIpAddress()}:{8002}");
- config.MapHttpAttributeRoutes();
- config.Routes.MapHttpRoute(name: "DefaultApi",
- routeTemplate: "api/{controller}/{action}",
- defaults: new { id = RouteParameter.Optional });
- new HttpSelfHostServer(config).OpenAsync();
- }
- private void App_Startup(object sender, StartupEventArgs e)
- {
- //UI线程未捕获异常处理事件
- DispatcherUnhandledException += new DispatcherUnhandledExceptionEventHandler(App_DispatcherUnhandledException);
- //Task线程内未捕获异常处理事件
- TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
- //非UI线程未捕获异常处理事件
- AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
- }
- void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
- {
- try
- {
- LogHelper.Error("UI线程异常:" + e.Exception.Message, e.Exception);
- }
- catch (Exception ex)
- {
- LogHelper.Error("UI线程异常trycatch:" + ex.Message, ex);
- }
- finally
- {
- e.Handled = true;
- }
- }
- void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
- {
- try
- {
- var exception = e.ExceptionObject as Exception;
- if (exception != null)
- {
- LogHelper.Error("非UI线程发生致命错误", exception);
- }
- }
- catch (Exception ex)
- {
- LogHelper.Error("非UI线程发生致命错误trycatch", ex);
- }
- finally
- {
- //此时程序出现严重异常,将强制结束退出
- Current.Shutdown();
- Process.Start(ResourceAssembly.Location);//重启软件
- }
- }
- void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
- {
- try
- {
- var exception = e.Exception as Exception;
- if (exception != null)
- {
- LogHelper.Error("Task线程异常:" + exception.Message, exception);
- }
- }
- catch (Exception ex)
- {
- LogHelper.Error("Task线程异常trycatch:" + ex.Message, ex);
- }
- finally
- {
- e.SetObserved();
- }
- }
- /// <summary>
- /// 修改程序在注册表中的键值
- /// </summary>
- /// <param name="isAuto">true:开机启动,false:不开机自启</param>
- public static void SetAutoStartByRegistry(bool isAuto, bool showInfo = true)
- {
- try
- {
- using (RegistryKey rLocal = Registry.CurrentUser)
- using (RegistryKey rRun = rLocal.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true))
- {
- if (rRun == null) return;
- if (isAuto)
- {
- string currentPath = Process.GetCurrentProcess().MainModule.FileName;
- object existingValue = rRun.GetValue(_appName);
- // 只有当值不存在或路径不同时才更新
- if (existingValue == null || !currentPath.Equals(existingValue.ToString(), StringComparison.OrdinalIgnoreCase))
- {
- rRun.SetValue(_appName, currentPath);
- }
- }
- else
- {
- // 如果存在则删除
- if (rRun.GetValue(_appName) != null)
- {
- rRun.DeleteValue(_appName, false);
- }
- }
- }
- }
- catch (UnauthorizedAccessException)
- {
- if (showInfo)
- {
- MessageBox.Show("需要管理员权限才能修改开机启动设置", "权限不足");
- }
- }
- catch (Exception ex)
- {
- if (showInfo)
- {
- MessageBox.Show($"修改开机启动设置时出错: {ex.Message}", "错误");
- }
- }
- }
- public static void SetAutoStartByStartupFolder(bool isAuto = true)
- {
- string appName = Config.AppName ?? "在线式钢丝绳电磁检测系统";
- string exePath = Process.GetCurrentProcess().MainModule.FileName;
- // 获取当前用户的启动文件夹路径
- string startupPath = Environment.GetFolderPath(Environment.SpecialFolder.Startup);
- string shortcutPath = Path.Combine(startupPath, $"{appName}.lnk");
- if (isAuto)
- {
- // 如果快捷方式已存在,先删除(防止重复或属性更新失败)
- if (System.IO.File.Exists(shortcutPath))
- System.IO.File.Delete(shortcutPath);
- // 创建 WshShell 对象
- WshShell shell = new WshShell();
- // 创建快捷方式
- IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(shortcutPath);
- // 设置快捷方式的属性
- shortcut.TargetPath = exePath; // 目标程序路径
- shortcut.WorkingDirectory = Path.GetDirectoryName(exePath); // 工作目录
- shortcut.Description = $"开机自启 - {appName}"; // 描述信息
- // 保存快捷方式文件
- shortcut.Save();
- Debug.WriteLine($"已创建启动快捷方式:{shortcutPath}");
- }
- else
- {
- // 删除快捷方式
- if (System.IO.File.Exists(shortcutPath))
- {
- System.IO.File.Delete(shortcutPath);
- Debug.WriteLine($"已删除启动快捷方式:{shortcutPath}");
- }
- }
- }
- /// <summary>
- /// 创建桌面会计快捷方式,要求管理员权限运行
- /// </summary>
- /// <param name="applicationPath"></param>
- /// <param name="shortcutName"></param>
- /// <returns></returns>
- public static bool CreateShortcut(string applicationPath, string shortcutName)
- {
- string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
- string shortcutPath = Path.Combine(desktopPath, shortcutName + ".lnk");
- // 检查快捷方式是否已存在
- if (System.IO.File.Exists(shortcutPath))
- {
- return false; // 已存在,不创建
- }
- try
- {
- WshShell shell = new WshShell();
- IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(shortcutPath);
- shortcut.TargetPath = applicationPath;
- shortcut.WorkingDirectory = Path.GetDirectoryName(applicationPath);
- shortcut.Description = "需要管理员权限运行";
- shortcut.IconLocation = applicationPath + ",0";
- // 保存快捷方式
- shortcut.Save();
- // 修改快捷方式以要求管理员权限
- using (var fs = new FileStream(shortcutPath, FileMode.Open, FileAccess.ReadWrite))
- {
- fs.Seek(21, SeekOrigin.Begin);
- fs.WriteByte(0x22); // 设置标志位以管理员身份运行
- }
- return true; // 创建成功
- }
- catch
- {
- // 如果创建过程中出错,尝试删除可能已部分创建的快捷方式
- if (System.IO.File.Exists(shortcutPath))
- {
- try { System.IO.File.Delete(shortcutPath); } catch { }
- }
- throw;
- }
- }
- public static void RestartApplication()
- {
- _singleInstanceManager?.Dispose();
- // 获取当前进程的可执行文件路径
- string currentExecutablePath = Process.GetCurrentProcess().MainModule.FileName;
- // 启动新的进程实例
- Process.Start(currentExecutablePath);
- // 关闭当前应用程序
- Current.Shutdown();
- }
- protected override void OnExit(ExitEventArgs e)
- {
- TcpServer?.Dispose();
- Calibration?.Dispose();
- HistoryCleanup?.Dispose();
- _singleInstanceManager?.Dispose();
- // 恢复此线程曾经阻止的系统休眠和屏幕关闭。
- SystemSleep.RestoreForCurrentThread();
- base.OnExit(e);
- }
- }
- }
|