鉤子卸載核心代碼
public void Stop()
{
this.Stop(true, true, true);
}
public void Stop(bool uninstallMouseHook, bool uninstallKeyboardHook, bool throwExceptions)
{
// 卸載滑鼠鉤子
if (hMouseHook != IntPtr.Zero && uninstallMouseHook)
{
bool retMouse = UnhookWindowsHookEx(hMouseHook);
hMouseHook = IntPtr.Zero;
if (!retMouse && throwExceptions)
{
int errorCode = Marshal.GetLastWin32Error();
throw new Win32Exception(errorCode);
}
}
// 卸載鍵盤鉤子
if (hKeyboardHook != IntPtr.Zero && uninstallKeyboardHook)
{
bool retKeyboard = UnhookWindowsHookEx(hKeyboardHook);
hKeyboardHook = IntPtr.Zero;
if (!retKeyboard && throwExceptions)
{
int errorCode = Marshal.GetLastWin32Error();
throw new Win32Exception(errorCode);
}
}
}
關鍵 API 與錯誤處理
- UnhookWindowsHookEx:卸載鉤子,回傳
true 表示成功
- Marshal.GetLastWin32Error:取得 Win32 錯誤碼
- Win32Exception:封裝系統錯誤碼的 .NET 異常
- IntPtr.Zero 重置:防止重複卸載或使用已釋放控制代碼
- 參數化控制:可獨立控制滑鼠/鍵盤鉤子卸載,支援選擇性釋放
析構函數建議
~UserActivityHook()
{
Stop(true, true, false); // 終結器不拋異常
}
資源管理原則
- 實作
IDisposable,提供 Dispose() 呼叫 Stop()
- 使用
using 區塊確保釋放
- 終結器作為安全網,但不拋異常
- 靜態變數持有鉤子控制代碼,避免 GC 過早回收委派