首頁 >後端開發 >C++ >為什麼我的 WPF C# 全域鍵盤掛鉤停止運作,如何修復它?

為什麼我的 WPF C# 全域鍵盤掛鉤停止運作,如何修復它?

Mary-Kate Olsen
Mary-Kate Olsen原創
2025-01-05 05:57:39301瀏覽

Why Does My WPF C# Global Keyboard Hook Stop Working, and How Can I Fix It?

在WPF / C# 中使用全域鍵盤鉤子(WH_KEYBOARD_LL)

解決鍵盤監聽在一段時間後解決鍵盤監聽時間必要了解問題的原因。問題的根源在於 SetHook 方法中建立和使用回呼委託的方式。

以下程式碼片段示範了這個問題:

public static IntPtr SetHook(LowLevelKeyboardProc proc)
{
    using (Process curProcess = Process.GetCurrentProcess())
    using (ProcessModule curModule = curProcess.MainModule)
    {
        return SetWindowsHookEx(WH_KEYBOARD_LL, proc,
            GetModuleHandle(curModule.ModuleName), 0);
    }
}

在此程式碼中,回呼delegate 是在 SetHook 方法呼叫中內嵌建立的,並指派給 proc 參數。但是,此委託未指派給類別或實例中的任何其他變數或屬性,這意味著沒有對它的參考來阻止它被垃圾收集。

當委託被垃圾收集時,函數指標傳遞給 SetWindowsHookEx 的值變得無效,並且不能再呼叫回呼。這就是為什麼偵聽器在一段時間後停止工作的原因。

要解決此問題,只要掛鉤就位,就必須保持對委託的引用處於活動狀態。這可以透過將委託分配給類別或實例中的欄位或屬性來實現。例如:

private static LowLevelKeyboardProc _proc;

public static IntPtr SetHook(LowLevelKeyboardProc proc)
{
    _proc = proc;
    using (Process curProcess = Process.GetCurrentProcess())
    using (ProcessModule curModule = curProcess.MainModule)
    {
        return SetWindowsHookEx(WH_KEYBOARD_LL, _proc,
            GetModuleHandle(curModule.ModuleName), 0);
    }
}

透過將委託分配給 _proc 字段,我們確保只要呼叫 SetHook 方法,它就保持活動狀態。這可以防止垃圾收集器收集委託並確保繼續呼叫回調。

以上是為什麼我的 WPF C# 全域鍵盤掛鉤停止運作,如何修復它?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn