首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 使用全域鉤子實作螢幕鍵盤(三):安裝鍵盤與滑鼠鉤子完整流程

     編輯:關於C語言

前言

本文為系列第三篇,詳細說明如何使用 SetWindowsHookEx 安裝低階鍵盤(WH_KEYBOARD_LL)與滑鼠(WH_MOUSE_LL)全域鉤子,涵蓋委托建立、模組控制代碼取得、錯誤處理與回滾機制。

安裝鉤子核心程式碼

public void Start(bool installMouseHook, bool installKeyboardHook)
{
    // 安裝滑鼠鉤子
    if (hMouseHook == IntPtr.Zero && installMouseHook)
    {
        MouseHookProcedure = new HookProc(MouseHookProc);
        hMouseHook = SetWindowsHookEx(
            WH_MOUSE_LL,
            MouseHookProcedure,
            Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]),
            0);

        if (hMouseHook == IntPtr.Zero)
        {
            int err = Marshal.GetLastWin32Error();
            Stop(true, false, false); // 回滾
            throw new Win32Exception(err);
        }
    }

    // 安裝鍵盤鉤子
    if (hKeyboardHook == IntPtr.Zero && installKeyboardHook)
    {
        KeyboardHookProcedure = new HookProc(KeyboardHookProc);
        hKeyboardHook = SetWindowsHookEx(
            WH_KEYBOARD_LL,
            KeyboardHookProcedure,
            Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]),
            0);

        if (hKeyboardHook == IntPtr.Zero)
        {
            int err = Marshal.GetLastWin32Error();
            Stop(false, true, false); // 回滾
            throw new Win32Exception(err);
        }
    }
}

關鍵技術細節

  1. 委托持有:HookProc 委托必須保持存活(存為欄位),否則 GC 回收導致回呼失效。
  2. 模組控制代碼:Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]) 取得目前組件的 HINSTANCE,全域鉤子必須在 DLL 中,但 .NET 組件即視為 DLL。
  3. 執行緒 ID 為 0:表示關聯所有執行緒,實現系統範圍攔截。
  4. 失敗回滾:安裝其中一個鉤子失敗時,立即卸載已成功安裝的另一個,避免殘留鉤子。
  5. 錯誤碼即時獲取:Marshal.GetLastWin32Error() 必須緊跟 SetWindowsHookEx 之後。

HookProc 簽名與回呼流程

private delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);

private IntPtr KeyboardHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{
    if (nCode >= 0)
    {
        // 處理鍵盤訊息,觸發事件通知 UI
        // ...
    }
    return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
}
  • nCode < 0:不可處理,直接傳遞下一個鉤子。
  • CallNextHookEx:將訊息傳遞給鉤子鏈中的下一個處理器,**必須呼叫**,否則阻斷系統訊息流。
  • 低階鉤子(LL)不需在獨立 DLL,直接在進程中實作即可。

結語

掌握 SetWindowsHookEx 正確安裝流程、委托生命週期管理與失敗回滾機制,是構建穩定全域鉤子應用的關鍵。下一篇將介紹滑鼠鉤子結構體定義與 SendInput 相關 API 封裝。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved