diff --git a/WIN10_WinISP_SrcCode_For_MOKA_20250416_1/WinISP/BaseClass/GraphicCardI2CCtrl.cs b/WIN10_WinISP_SrcCode_For_MOKA_20250416_1/WinISP/BaseClass/GraphicCardI2CCtrl.cs
index 6ea107e..4b7f1b2 100644
--- a/WIN10_WinISP_SrcCode_For_MOKA_20250416_1/WinISP/BaseClass/GraphicCardI2CCtrl.cs
+++ b/WIN10_WinISP_SrcCode_For_MOKA_20250416_1/WinISP/BaseClass/GraphicCardI2CCtrl.cs
@@ -144,15 +144,165 @@ namespace WinISP.BaseClass
}
}
+ private readonly object _graphicsCardLock = new object();
+ private volatile bool _isDisposing = false;
+
private void FreeGraphicsCardCtrl()
{
- // Free the GCHandle.
- frmISP.WriteLog("Free the GCHandle.", "debug");
- if (gch.IsAllocated)
- gch.Free();
- DisposeGraphicCardCtrl();
- pGraphicCardCtrl = IntPtr.Zero;
- _IsInit = false;
+ lock (_graphicsCardLock)
+ {
+ // 防止重复释放
+ if (_isDisposing)
+ {
+ frmISP.WriteLog("Graphics card control is already being disposed, skipping.", "warn");
+ return;
+ }
+
+ if (!_IsInit)
+ {
+ frmISP.WriteLog("Graphics card control is not initialized, nothing to free.", "debug");
+ return;
+ }
+
+ _isDisposing = true;
+
+ try
+ {
+ // 第一步:释放 GCHandle
+ FreeGCHandle();
+
+ // 第二步:释放图形卡控制资源
+ DisposeGraphicsCardControl();
+
+ // 第三步:清空指针
+ pGraphicCardCtrl = IntPtr.Zero;
+
+ // 第四步:更新状态
+ _IsInit = false;
+
+ frmISP.WriteLog("Graphics card control freed successfully.", "info");
+ }
+ catch (Exception ex)
+ {
+ frmISP.WriteLog($"Error freeing graphics card control: {ex.GetType().Name} - {ex.Message}", "error");
+ // 即使出错也要尝试清理状态
+ try
+ {
+ pGraphicCardCtrl = IntPtr.Zero;
+ _IsInit = false;
+ }
+ catch (Exception cleanupEx)
+ {
+ frmISP.WriteLog($"Error during cleanup after exception: {cleanupEx.Message}", "error");
+ }
+ }
+ finally
+ {
+ _isDisposing = false;
+ }
+ }
+ }
+
+ ///
+ /// 安全释放 GCHandle
+ ///
+ private void FreeGCHandle()
+ {
+ try
+ {
+ if (gch.IsAllocated)
+ {
+ frmISP.WriteLog("Freeing GCHandle...", "debug");
+ gch.Free();
+ frmISP.WriteLog("GCHandle freed successfully.", "debug");
+ }
+ else
+ {
+ frmISP.WriteLog("GCHandle is not allocated, skipping free operation.", "debug");
+ }
+ }
+ catch (InvalidOperationException ex)
+ {
+ frmISP.WriteLog($"InvalidOperationException when freeing GCHandle: {ex.Message}", "warn");
+ }
+ catch (Exception ex)
+ {
+ frmISP.WriteLog($"Unexpected exception when freeing GCHandle: {ex.GetType().Name} - {ex.Message}", "error");
+ }
+ }
+
+ ///
+ /// 安全释放图形卡控制资源
+ ///
+ private void DisposeGraphicsCardControl()
+ {
+ try
+ {
+ if (pGraphicCardCtrl != IntPtr.Zero)
+ {
+ frmISP.WriteLog("Disposing graphics card control...", "debug");
+ DisposeGraphicCardCtrl();
+ frmISP.WriteLog("Graphics card control disposed successfully.", "debug");
+ }
+ else
+ {
+ frmISP.WriteLog("Graphics card control pointer is null, skipping dispose.", "debug");
+ }
+ }
+ catch (AccessViolationException ex)
+ {
+ frmISP.WriteLog($"AccessViolationException when disposing graphics card control: {ex.Message}", "error");
+ }
+ catch (ObjectDisposedException ex)
+ {
+ frmISP.WriteLog($"ObjectDisposedException when disposing graphics card control: {ex.Message}", "warn");
+ }
+ catch (Exception ex)
+ {
+ frmISP.WriteLog($"Unexpected exception when disposing graphics card control: {ex.GetType().Name} - {ex.Message}", "error");
+ }
+ }
+
+ ///
+ /// 验证图形卡控制是否已正确释放
+ ///
+ public bool IsGraphicsCardControlFreed()
+ {
+ lock (_graphicsCardLock)
+ {
+ return !_IsInit && pGraphicCardCtrl == IntPtr.Zero && !gch.IsAllocated;
+ }
+ }
+
+ ///
+ /// 强制清理(用于异常恢复)
+ ///
+ public void ForceCleanupGraphicsCardCtrl()
+ {
+ lock (_graphicsCardLock)
+ {
+ try
+ {
+ frmISP.WriteLog("Performing force cleanup of graphics card control...", "warn");
+
+ // 强制释放 GCHandle
+ if (gch.IsAllocated)
+ {
+ try { gch.Free(); }
+ catch { }
+ }
+
+ // 强制清空指针
+ pGraphicCardCtrl = IntPtr.Zero;
+ _IsInit = false;
+
+ frmISP.WriteLog("Force cleanup completed.", "info");
+ }
+ catch (Exception ex)
+ {
+ frmISP.WriteLog($"Error during force cleanup: {ex.Message}", "error");
+ }
+ }
}
public GraphicCardI2CCtrl()
diff --git a/WIN10_WinISP_SrcCode_For_MOKA_20250416_1/WinISP/FormISP_MSI.cs b/WIN10_WinISP_SrcCode_For_MOKA_20250416_1/WinISP/FormISP_MSI.cs
index fec742c..768a467 100644
--- a/WIN10_WinISP_SrcCode_For_MOKA_20250416_1/WinISP/FormISP_MSI.cs
+++ b/WIN10_WinISP_SrcCode_For_MOKA_20250416_1/WinISP/FormISP_MSI.cs
@@ -125,15 +125,125 @@ namespace WinISP
public void CheckSingleInstance()
{
- Process[] thisnameprocesslist;
- string modulename, processname;
- Process p = Process.GetCurrentProcess();
- modulename = p.MainModule.ModuleName.ToString();
- processname = System.IO.Path.GetFileNameWithoutExtension(modulename);
- thisnameprocesslist = Process.GetProcessesByName(processname);
- if (thisnameprocesslist.Length > 1)
+ Process currentProcess = null;
+ Process[] processList = null;
+
+ try
{
- Application.Exit();
+ currentProcess = Process.GetCurrentProcess();
+
+ // 安全获取模块名称
+ if (currentProcess.MainModule == null)
+ {
+ frmISP.WriteLog("Failed to get MainModule, cannot perform single instance check", "error");
+ return;
+ }
+
+ string moduleName = currentProcess.MainModule.ModuleName;
+ string processName = System.IO.Path.GetFileNameWithoutExtension(moduleName);
+
+ frmISP.WriteLog($"Current process name: {processName}, PID: {currentProcess.Id}", "debug");
+
+ // 获取同名进程列表
+ processList = Process.GetProcessesByName(processName);
+
+ frmISP.WriteLog($"Found {processList.Length} process(es) with name '{processName}'", "debug");
+
+ // 检查是否存在多个实例
+ if (processList.Length > 1)
+ {
+ frmISP.WriteLog($"Multiple instances detected ({processList.Length}). Exiting application.", "warn");
+
+ // 可选:激活已存在的实例窗口
+ ActivateExistingInstance(processList, currentProcess.Id);
+
+ Application.Exit();
+ }
+ else
+ {
+ frmISP.WriteLog("Single instance check passed. Application is running as the only instance.", "debug");
+ }
+ }
+ catch (System.ComponentModel.Win32Exception ex)
+ {
+ frmISP.WriteLog($"Win32Exception in CheckSingleInstance: {ex.Message}", "error");
+ }
+ catch (UnauthorizedAccessException ex)
+ {
+ frmISP.WriteLog($"UnauthorizedAccessException in CheckSingleInstance: {ex.Message}", "error");
+ }
+ catch (Exception ex)
+ {
+ frmISP.WriteLog($"Unexpected exception in CheckSingleInstance: {ex.GetType().Name} - {ex.Message}", "error");
+ }
+ finally
+ {
+ // 释放 Process 资源
+ if (processList != null)
+ {
+ foreach (var p in processList)
+ {
+ p?.Dispose();
+ }
+ }
+ currentProcess?.Dispose();
+ }
+ }
+
+ ///
+ /// 尝试激活已存在的应用实例窗口
+ ///
+ private void ActivateExistingInstance(Process[] processList, int currentPid)
+ {
+ try
+ {
+ foreach (var process in processList)
+ {
+ // 跳过当前进程
+ if (process.Id == currentPid)
+ continue;
+
+ // 尝试获取主窗口句柄
+ if (process.MainWindowHandle != IntPtr.Zero)
+ {
+ // 恢复窗口(如果最小化)
+ if (IsWindowMinimized(process.MainWindowHandle))
+ {
+ ShowWindow(process.MainWindowHandle, 9); // SW_RESTORE
+ }
+
+ // 激活窗口
+ SetForegroundWindow(process.MainWindowHandle);
+ frmISP.WriteLog($"Activated existing instance (PID: {process.Id})", "info");
+ return;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ frmISP.WriteLog($"Failed to activate existing instance: {ex.Message}", "warn");
+ }
+ }
+
+ // Windows API 声明
+ [System.Runtime.InteropServices.DllImport("user32.dll")]
+ private static extern bool SetForegroundWindow(IntPtr hWnd);
+
+ [System.Runtime.InteropServices.DllImport("user32.dll")]
+ private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
+
+ [System.Runtime.InteropServices.DllImport("user32.dll")]
+ private static extern bool IsIconic(IntPtr hWnd);
+
+ private bool IsWindowMinimized(IntPtr hWnd)
+ {
+ try
+ {
+ return IsIconic(hWnd);
+ }
+ catch
+ {
+ return false;
}
}