improve:卡死检测
This commit is contained in:
+177
-40
@@ -445,16 +445,41 @@ namespace Ink_Canvas
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
LogHelper.WriteLogToFile("开始创建启动画面...");
|
LogHelper.WriteLogToFile("开始创建启动画面...");
|
||||||
|
|
||||||
|
UpdateHeartbeatOnUIThread();
|
||||||
|
|
||||||
_splashScreen = new SplashScreen();
|
_splashScreen = new SplashScreen();
|
||||||
LogHelper.WriteLogToFile("启动画面对象创建成功,准备显示...");
|
LogHelper.WriteLogToFile("启动画面对象创建成功,准备显示...");
|
||||||
_splashScreen.Show();
|
|
||||||
_isSplashScreenShown = true;
|
UpdateHeartbeatOnUIThread();
|
||||||
LogHelper.WriteLogToFile("启动画面已显示");
|
|
||||||
|
if (Current?.Dispatcher != null && !Current.Dispatcher.HasShutdownStarted)
|
||||||
|
{
|
||||||
|
Current.Dispatcher.Invoke(() =>
|
||||||
|
{
|
||||||
|
_splashScreen.Show();
|
||||||
|
_isSplashScreenShown = true;
|
||||||
|
|
||||||
|
Current.Dispatcher.Invoke(() => { }, DispatcherPriority.Render);
|
||||||
|
|
||||||
|
UpdateHeartbeatOnUIThread();
|
||||||
|
|
||||||
|
LogHelper.WriteLogToFile("启动画面已显示");
|
||||||
|
}, DispatcherPriority.Normal);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_splashScreen.Show();
|
||||||
|
_isSplashScreenShown = true;
|
||||||
|
UpdateHeartbeatOnUIThread();
|
||||||
|
LogHelper.WriteLogToFile("启动画面已显示");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
LogHelper.WriteLogToFile($"显示启动画面失败: {ex.Message}", LogHelper.LogType.Error);
|
LogHelper.WriteLogToFile($"显示启动画面失败: {ex.Message}", LogHelper.LogType.Error);
|
||||||
LogHelper.WriteLogToFile($"异常堆栈: {ex.StackTrace}", LogHelper.LogType.Error);
|
LogHelper.WriteLogToFile($"异常堆栈: {ex.StackTrace}", LogHelper.LogType.Error);
|
||||||
|
UpdateHeartbeatOnUIThread();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -641,26 +666,35 @@ namespace Ink_Canvas
|
|||||||
|
|
||||||
async void App_Startup(object sender, StartupEventArgs e)
|
async void App_Startup(object sender, StartupEventArgs e)
|
||||||
{
|
{
|
||||||
// 初始化应用启动时间
|
|
||||||
appStartTime = DateTime.Now;
|
appStartTime = DateTime.Now;
|
||||||
|
|
||||||
|
UpdateHeartbeatOnUIThread();
|
||||||
|
|
||||||
// 根据设置决定是否显示启动画面
|
|
||||||
if (ShouldShowSplashScreen())
|
if (ShouldShowSplashScreen())
|
||||||
{
|
{
|
||||||
ShowSplashScreen();
|
ShowSplashScreen();
|
||||||
SetSplashMessage("正在启动 Ink Canvas...");
|
SetSplashMessage("正在启动 Ink Canvas...");
|
||||||
SetSplashProgress(20);
|
SetSplashProgress(20);
|
||||||
|
|
||||||
|
UpdateHeartbeatOnUIThread();
|
||||||
|
|
||||||
await Task.Delay(500);
|
await Task.Delay(500);
|
||||||
|
|
||||||
// 强制刷新UI,确保启动画面显示
|
Application.Current.Dispatcher.Invoke(() =>
|
||||||
Application.Current.Dispatcher.Invoke(() => { }, DispatcherPriority.Render);
|
{
|
||||||
|
UpdateHeartbeatOnUIThread();
|
||||||
|
}, DispatcherPriority.Render);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateHeartbeatOnUIThread();
|
||||||
|
|
||||||
System.Threading.Thread.Sleep(500);
|
System.Threading.Thread.Sleep(500);
|
||||||
RootPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
|
RootPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
|
||||||
|
|
||||||
LogHelper.NewLog(string.Format("Ink Canvas Starting (Version: {0})", Assembly.GetExecutingAssembly().GetName().Version));
|
LogHelper.NewLog(string.Format("Ink Canvas Starting (Version: {0})", Assembly.GetExecutingAssembly().GetName().Version));
|
||||||
|
|
||||||
|
UpdateHeartbeatOnUIThread();
|
||||||
|
|
||||||
// 检查是否为最终应用启动(更新后的应用)
|
// 检查是否为最终应用启动(更新后的应用)
|
||||||
bool isFinalApp = e.Args.Contains("--final-app");
|
bool isFinalApp = e.Args.Contains("--final-app");
|
||||||
bool skipMutexCheck = e.Args.Contains("--skip-mutex-check");
|
bool skipMutexCheck = e.Args.Contains("--skip-mutex-check");
|
||||||
@@ -687,49 +721,61 @@ namespace Ink_Canvas
|
|||||||
LogHelper.WriteLogToFile("App | 检测到最终应用启动(更新后的应用)");
|
LogHelper.WriteLogToFile("App | 检测到最终应用启动(更新后的应用)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 释放IACore相关DLL
|
|
||||||
if (_isSplashScreenShown)
|
if (_isSplashScreenShown)
|
||||||
{
|
{
|
||||||
SetSplashMessage("正在初始化组件...");
|
SetSplashMessage("正在初始化组件...");
|
||||||
SetSplashProgress(40);
|
SetSplashProgress(40);
|
||||||
await Task.Delay(500);
|
await Task.Delay(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateHeartbeatOnUIThread();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
IACoreDllExtractor.ExtractIACoreDlls();
|
IACoreDllExtractor.ExtractIACoreDlls();
|
||||||
|
UpdateHeartbeatOnUIThread();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
LogHelper.WriteLogToFile($"释放IACore DLL时出错: {ex.Message}", LogHelper.LogType.Error);
|
LogHelper.WriteLogToFile($"释放IACore DLL时出错: {ex.Message}", LogHelper.LogType.Error);
|
||||||
|
UpdateHeartbeatOnUIThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 释放UIAccess DLL
|
|
||||||
if (_isSplashScreenShown)
|
if (_isSplashScreenShown)
|
||||||
{
|
{
|
||||||
SetSplashMessage("正在初始化组件...");
|
SetSplashMessage("正在初始化组件...");
|
||||||
SetSplashProgress(50);
|
SetSplashProgress(50);
|
||||||
await Task.Delay(300);
|
await Task.Delay(300);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateHeartbeatOnUIThread();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
UIAccessDllExtractor.ExtractUIAccessDlls();
|
UIAccessDllExtractor.ExtractUIAccessDlls();
|
||||||
|
UpdateHeartbeatOnUIThread();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
LogHelper.WriteLogToFile($"释放UIAccess DLL时出错: {ex.Message}", LogHelper.LogType.Error);
|
LogHelper.WriteLogToFile($"释放UIAccess DLL时出错: {ex.Message}", LogHelper.LogType.Error);
|
||||||
|
UpdateHeartbeatOnUIThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 记录应用启动(设备标识符)
|
|
||||||
if (_isSplashScreenShown)
|
if (_isSplashScreenShown)
|
||||||
{
|
{
|
||||||
SetSplashMessage("正在加载配置...");
|
SetSplashMessage("正在加载配置...");
|
||||||
SetSplashProgress(60);
|
SetSplashProgress(60);
|
||||||
await Task.Delay(500);
|
await Task.Delay(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateHeartbeatOnUIThread();
|
||||||
|
|
||||||
DeviceIdentifier.RecordAppLaunch();
|
DeviceIdentifier.RecordAppLaunch();
|
||||||
LogHelper.WriteLogToFile($"App | 设备ID: {DeviceIdentifier.GetDeviceId()}");
|
LogHelper.WriteLogToFile($"App | 设备ID: {DeviceIdentifier.GetDeviceId()}");
|
||||||
LogHelper.WriteLogToFile($"App | 使用频率: {DeviceIdentifier.GetUsageFrequency()}");
|
LogHelper.WriteLogToFile($"App | 使用频率: {DeviceIdentifier.GetUsageFrequency()}");
|
||||||
LogHelper.WriteLogToFile($"App | 更新优先级: {DeviceIdentifier.GetUpdatePriority()}");
|
LogHelper.WriteLogToFile($"App | 更新优先级: {DeviceIdentifier.GetUpdatePriority()}");
|
||||||
|
|
||||||
|
UpdateHeartbeatOnUIThread();
|
||||||
|
|
||||||
// 处理更新模式启动
|
// 处理更新模式启动
|
||||||
bool isUpdateMode = AutoUpdateHelper.HandleUpdateModeStartup(e.Args);
|
bool isUpdateMode = AutoUpdateHelper.HandleUpdateModeStartup(e.Args);
|
||||||
@@ -981,19 +1027,27 @@ namespace Ink_Canvas
|
|||||||
|
|
||||||
StartArgs = e.Args;
|
StartArgs = e.Args;
|
||||||
|
|
||||||
// 在非更新模式下创建主窗口
|
|
||||||
if (_isSplashScreenShown)
|
if (_isSplashScreenShown)
|
||||||
{
|
{
|
||||||
SetSplashMessage("正在初始化主界面...");
|
SetSplashMessage("正在初始化主界面...");
|
||||||
SetSplashProgress(80);
|
SetSplashProgress(80);
|
||||||
await Task.Delay(500);
|
await Task.Delay(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateHeartbeatOnUIThread();
|
||||||
|
|
||||||
var mainWindow = new MainWindow();
|
var mainWindow = new MainWindow();
|
||||||
MainWindow = mainWindow;
|
MainWindow = mainWindow;
|
||||||
|
|
||||||
|
UpdateHeartbeatOnUIThread();
|
||||||
|
|
||||||
// 主窗口加载完成后关闭启动画面
|
|
||||||
mainWindow.Loaded += (s, args) =>
|
mainWindow.Loaded += (s, args) =>
|
||||||
{
|
{
|
||||||
|
UpdateHeartbeatOnUIThread();
|
||||||
|
|
||||||
|
isStartupPhase = false;
|
||||||
|
LogHelper.WriteLogToFile("心跳监控 | 主窗口加载完成,启动阶段结束");
|
||||||
|
|
||||||
if (_isSplashScreenShown)
|
if (_isSplashScreenShown)
|
||||||
{
|
{
|
||||||
SetSplashMessage("完成初始化...");
|
SetSplashMessage("完成初始化...");
|
||||||
@@ -1004,10 +1058,15 @@ namespace Ink_Canvas
|
|||||||
{
|
{
|
||||||
SetSplashMessage("启动完成!");
|
SetSplashMessage("启动完成!");
|
||||||
SetSplashProgress(100);
|
SetSplashProgress(100);
|
||||||
// 延迟关闭启动画面,让用户看到完成消息
|
UpdateHeartbeatOnUIThread();
|
||||||
|
|
||||||
Task.Delay(500).ContinueWith(__ =>
|
Task.Delay(500).ContinueWith(__ =>
|
||||||
{
|
{
|
||||||
Dispatcher.Invoke(() => CloseSplashScreen());
|
Dispatcher.Invoke(() =>
|
||||||
|
{
|
||||||
|
CloseSplashScreen();
|
||||||
|
UpdateHeartbeatOnUIThread();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -1015,30 +1074,37 @@ namespace Ink_Canvas
|
|||||||
};
|
};
|
||||||
|
|
||||||
mainWindow.Show();
|
mainWindow.Show();
|
||||||
|
|
||||||
|
UpdateHeartbeatOnUIThread();
|
||||||
|
|
||||||
// 注册.icstk文件关联
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
LogHelper.WriteLogToFile("开始注册.icstk文件关联");
|
LogHelper.WriteLogToFile("开始注册.icstk文件关联");
|
||||||
FileAssociationManager.RegisterFileAssociation();
|
FileAssociationManager.RegisterFileAssociation();
|
||||||
FileAssociationManager.ShowFileAssociationStatus();
|
FileAssociationManager.ShowFileAssociationStatus();
|
||||||
|
UpdateHeartbeatOnUIThread();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
LogHelper.WriteLogToFile($"注册文件关联时出错: {ex.Message}", LogHelper.LogType.Error);
|
LogHelper.WriteLogToFile($"注册文件关联时出错: {ex.Message}", LogHelper.LogType.Error);
|
||||||
|
UpdateHeartbeatOnUIThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 启动IPC监听器
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
LogHelper.WriteLogToFile("启动IPC监听器");
|
LogHelper.WriteLogToFile("启动IPC监听器");
|
||||||
FileAssociationManager.StartIpcListener();
|
FileAssociationManager.StartIpcListener();
|
||||||
|
UpdateHeartbeatOnUIThread();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
LogHelper.WriteLogToFile($"启动IPC监听器时出错: {ex.Message}", LogHelper.LogType.Error);
|
LogHelper.WriteLogToFile($"启动IPC监听器时出错: {ex.Message}", LogHelper.LogType.Error);
|
||||||
|
UpdateHeartbeatOnUIThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateHeartbeatOnUIThread();
|
||||||
|
LogHelper.WriteLogToFile("心跳监控 | 应用启动流程完成");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
|
private void ScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
|
||||||
@@ -1066,40 +1132,107 @@ namespace Ink_Canvas
|
|||||||
NoAction
|
NoAction
|
||||||
}
|
}
|
||||||
|
|
||||||
// 心跳相关
|
|
||||||
private static Timer heartbeatTimer;
|
private static Timer heartbeatTimer;
|
||||||
private static DateTime lastHeartbeat = DateTime.Now;
|
private static DateTime lastHeartbeat = DateTime.Now;
|
||||||
private static Timer watchdogTimer;
|
private static Timer watchdogTimer;
|
||||||
|
private static DispatcherTimer uiHeartbeatTimer;
|
||||||
|
private static bool isStartupPhase = true;
|
||||||
|
private static DateTime startupStartTime = DateTime.Now;
|
||||||
|
|
||||||
|
public static void UpdateHeartbeatOnUIThread()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (Current?.Dispatcher != null && !Current.Dispatcher.HasShutdownStarted)
|
||||||
|
{
|
||||||
|
Current.Dispatcher.Invoke(() =>
|
||||||
|
{
|
||||||
|
lastHeartbeat = DateTime.Now;
|
||||||
|
Current.Dispatcher.Invoke(() => { }, DispatcherPriority.Background);
|
||||||
|
}, DispatcherPriority.Normal);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lastHeartbeat = DateTime.Now;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
lastHeartbeat = DateTime.Now;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void StartHeartbeatMonitor()
|
private void StartHeartbeatMonitor()
|
||||||
{
|
{
|
||||||
// 主线程定时更新心跳
|
startupStartTime = DateTime.Now;
|
||||||
heartbeatTimer = new Timer(_ => lastHeartbeat = DateTime.Now, null, 0, 1000);
|
|
||||||
// 辅助线程检测心跳超时
|
heartbeatTimer = new Timer(_ =>
|
||||||
|
{
|
||||||
|
if ((DateTime.Now - lastHeartbeat).TotalSeconds > 2)
|
||||||
|
{
|
||||||
|
lastHeartbeat = DateTime.Now;
|
||||||
|
}
|
||||||
|
}, null, 0, 1000);
|
||||||
|
|
||||||
|
if (Current?.Dispatcher != null)
|
||||||
|
{
|
||||||
|
uiHeartbeatTimer = new DispatcherTimer
|
||||||
|
{
|
||||||
|
Interval = TimeSpan.FromMilliseconds(500)
|
||||||
|
};
|
||||||
|
uiHeartbeatTimer.Tick += (s, e) =>
|
||||||
|
{
|
||||||
|
lastHeartbeat = DateTime.Now;
|
||||||
|
Current.Dispatcher.Invoke(() => { }, DispatcherPriority.Background);
|
||||||
|
};
|
||||||
|
uiHeartbeatTimer.Start();
|
||||||
|
}
|
||||||
|
|
||||||
watchdogTimer = new Timer(_ =>
|
watchdogTimer = new Timer(_ =>
|
||||||
{
|
{
|
||||||
if ((DateTime.Now - lastHeartbeat).TotalSeconds > 10)
|
try
|
||||||
{
|
{
|
||||||
LogHelper.NewLog("检测到主线程无响应,自动重启。");
|
double timeSinceLastHeartbeat = (DateTime.Now - lastHeartbeat).TotalSeconds;
|
||||||
SyncCrashActionFromSettings(); // 新增:心跳检测时同步最新设置
|
double timeSinceStartup = (DateTime.Now - startupStartTime).TotalSeconds;
|
||||||
if (CrashAction == CrashActionType.SilentRestart)
|
|
||||||
|
double timeoutThreshold = isStartupPhase ? 30.0 : 10.0;
|
||||||
|
|
||||||
|
if (isStartupPhase && timeSinceStartup > 60)
|
||||||
{
|
{
|
||||||
StartupCount.Increment();
|
isStartupPhase = false;
|
||||||
if (StartupCount.GetCount() >= 5)
|
LogHelper.WriteLogToFile("心跳监控 | 启动阶段结束,切换到正常运行模式");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timeSinceLastHeartbeat > timeoutThreshold)
|
||||||
|
{
|
||||||
|
string phase = isStartupPhase ? "启动阶段" : "运行阶段";
|
||||||
|
LogHelper.WriteLogToFile($"心跳监控 | 检测到主线程无响应({phase},超时{timeoutThreshold}秒),准备自动重启。");
|
||||||
|
LogHelper.WriteLogToFile($"心跳监控 | 距离上次心跳: {timeSinceLastHeartbeat:F1}秒,距离启动: {timeSinceStartup:F1}秒");
|
||||||
|
|
||||||
|
SyncCrashActionFromSettings();
|
||||||
|
if (CrashAction == CrashActionType.SilentRestart)
|
||||||
{
|
{
|
||||||
MessageBox.Show("检测到程序已连续重启5次,已停止自动重启。请联系开发者或检查系统环境。", "重启次数过多", MessageBoxButton.OK, MessageBoxImage.Error);
|
StartupCount.Increment();
|
||||||
StartupCount.Reset();
|
if (StartupCount.GetCount() >= 5)
|
||||||
|
{
|
||||||
|
MessageBox.Show("检测到程序已连续重启5次,已停止自动重启。请联系开发者或检查系统环境。", "重启次数过多", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
|
StartupCount.Reset();
|
||||||
|
Environment.Exit(1);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string exePath = Process.GetCurrentProcess().MainModule.FileName;
|
||||||
|
Process.Start(exePath);
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
Environment.Exit(1);
|
Environment.Exit(1);
|
||||||
}
|
}
|
||||||
try
|
|
||||||
{
|
|
||||||
string exePath = Process.GetCurrentProcess().MainModule.FileName;
|
|
||||||
Process.Start(exePath);
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
Environment.Exit(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"心跳监控 | 检测过程出错: {ex.Message}", LogHelper.LogType.Warning);
|
||||||
|
}
|
||||||
}, null, 0, 3000);
|
}, null, 0, 3000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1170,14 +1303,20 @@ namespace Ink_Canvas
|
|||||||
|
|
||||||
private void App_Exit(object sender, ExitEventArgs e)
|
private void App_Exit(object sender, ExitEventArgs e)
|
||||||
{
|
{
|
||||||
// 仅在软件内主动退出时关闭看门狗,并写入退出信号
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 记录应用退出状态
|
heartbeatTimer?.Dispose();
|
||||||
|
watchdogTimer?.Dispose();
|
||||||
|
uiHeartbeatTimer?.Stop();
|
||||||
|
uiHeartbeatTimer = null;
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
string exitType = IsAppExitByUser ? "用户主动退出" : "应用程序退出";
|
string exitType = IsAppExitByUser ? "用户主动退出" : "应用程序退出";
|
||||||
WriteCrashLog($"{exitType},退出代码: {e.ApplicationExitCode}");
|
WriteCrashLog($"{exitType},退出代码: {e.ApplicationExitCode}");
|
||||||
|
|
||||||
// 记录应用退出(设备标识符)
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
DeviceIdentifier.RecordAppExit();
|
DeviceIdentifier.RecordAppExit();
|
||||||
@@ -1190,7 +1329,6 @@ namespace Ink_Canvas
|
|||||||
|
|
||||||
if (IsAppExitByUser)
|
if (IsAppExitByUser)
|
||||||
{
|
{
|
||||||
// 写入退出信号文件,通知看门狗正常退出
|
|
||||||
StartupCount.Reset();
|
StartupCount.Reset();
|
||||||
File.WriteAllText(watchdogExitSignalFile, "exit");
|
File.WriteAllText(watchdogExitSignalFile, "exit");
|
||||||
if (watchdogProcess != null && !watchdogProcess.HasExited)
|
if (watchdogProcess != null && !watchdogProcess.HasExited)
|
||||||
@@ -1201,7 +1339,6 @@ namespace Ink_Canvas
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
// 尝试记录最后的错误
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
LogHelper.WriteLogToFile($"退出处理时发生错误: {ex.Message}", LogHelper.LogType.Error);
|
LogHelper.WriteLogToFile($"退出处理时发生错误: {ex.Message}", LogHelper.LogType.Error);
|
||||||
|
|||||||
Reference in New Issue
Block a user