增加日志,完善逻辑
This commit is contained in:
@@ -144,15 +144,165 @@ namespace WinISP.BaseClass
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private readonly object _graphicsCardLock = new object();
|
||||||
|
private volatile bool _isDisposing = false;
|
||||||
|
|
||||||
private void FreeGraphicsCardCtrl()
|
private void FreeGraphicsCardCtrl()
|
||||||
{
|
{
|
||||||
// Free the GCHandle.
|
lock (_graphicsCardLock)
|
||||||
frmISP.WriteLog("Free the GCHandle.", "debug");
|
{
|
||||||
if (gch.IsAllocated)
|
// 防止重复释放
|
||||||
gch.Free();
|
if (_isDisposing)
|
||||||
DisposeGraphicCardCtrl();
|
{
|
||||||
pGraphicCardCtrl = IntPtr.Zero;
|
frmISP.WriteLog("Graphics card control is already being disposed, skipping.", "warn");
|
||||||
_IsInit = false;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 安全释放 GCHandle
|
||||||
|
/// </summary>
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 安全释放图形卡控制资源
|
||||||
|
/// </summary>
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 验证图形卡控制是否已正确释放
|
||||||
|
/// </summary>
|
||||||
|
public bool IsGraphicsCardControlFreed()
|
||||||
|
{
|
||||||
|
lock (_graphicsCardLock)
|
||||||
|
{
|
||||||
|
return !_IsInit && pGraphicCardCtrl == IntPtr.Zero && !gch.IsAllocated;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 强制清理(用于异常恢复)
|
||||||
|
/// </summary>
|
||||||
|
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()
|
public GraphicCardI2CCtrl()
|
||||||
|
|||||||
@@ -125,15 +125,125 @@ namespace WinISP
|
|||||||
|
|
||||||
public void CheckSingleInstance()
|
public void CheckSingleInstance()
|
||||||
{
|
{
|
||||||
Process[] thisnameprocesslist;
|
Process currentProcess = null;
|
||||||
string modulename, processname;
|
Process[] processList = null;
|
||||||
Process p = Process.GetCurrentProcess();
|
|
||||||
modulename = p.MainModule.ModuleName.ToString();
|
try
|
||||||
processname = System.IO.Path.GetFileNameWithoutExtension(modulename);
|
|
||||||
thisnameprocesslist = Process.GetProcessesByName(processname);
|
|
||||||
if (thisnameprocesslist.Length > 1)
|
|
||||||
{
|
{
|
||||||
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 尝试激活已存在的应用实例窗口
|
||||||
|
/// </summary>
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user