在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中文網其他相關文章!