首页 >后端开发 >C++ >为什么我的 WPF C# 全局键盘挂钩停止工作,如何修复它?

为什么我的 WPF C# 全局键盘挂钩停止工作,如何修复它?

Mary-Kate Olsen
Mary-Kate Olsen原创
2025-01-05 05:57:39298浏览

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