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