首页 >后端开发 >C++ >为什么 C# 中的全局键盘挂钩在持续击键后停止工作?

为什么 C# 中的全局键盘挂钩在持续击键后停止工作?

Barbara Streisand
Barbara Streisand原创
2025-01-03 08:34:42316浏览

Why Does My Global Keyboard Hook in C# Stop Working After Sustained Keystrokes?

在 WPF / C# 中使用全局键盘钩子 (WH_KEYBOARD_LL)

提供的代码旨在使用 WH_KEYBOARD_LL 钩子建立一个全局键盘钩子捕获并处理键盘事件。虽然实现基本上实现了其预期功能,但出现了一个关键问题:在持续击键一段时间后,事件处理突然停止。

此行为表明存在潜在的线程问题。为了解决这个问题,我们需要确保只要钩子就位,回调委托就保持活动状态。

问题分析

回调委托 HookCallback 是在 SetHook 方法中内联定义。因此,一旦方法退出,委托就有资格进行垃圾回收。发生这种情况时,挂钩将停止接收回调,从而导致观察到事件处理终止。

解决方案

要纠正此问题,我们需要保留对委托并确保其生命周期与钩子的存在一致。以下是解决该问题的修订后的代码:

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Windows.Input;

namespace MYCOMPANYHERE.WPF.KeyboardHelper
{
    public class KeyboardListener : IDisposable
    {
        private static IntPtr hookId = IntPtr.Zero;
        private InterceptKeys.LowLevelKeyboardProc callback;

        public KeyboardListener()
        {
            callback = HookCallback;
            hookId = InterceptKeys.SetHook(callback);
        }

        [MethodImpl(MethodImplOptions.NoInlining)]
        private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            try
            {
                return HookCallbackInner(nCode, wParam, lParam);
            }
            catch
            {
                Console.WriteLine("There was some error somewhere...");
            }
            return InterceptKeys.CallNextHookEx(hookId, nCode, wParam, lParam);
        }

        private IntPtr HookCallbackInner(int nCode, IntPtr wParam, IntPtr lParam)
        {
            // ... (original code here)

            return InterceptKeys.CallNextHookEx(hookId, nCode, wParam, lParam);
        }

        // ... (rest of the class)
    }
}

在此更新的代码中,LowLevelKeyboardProc 委托(回调)现在是 KeyboardListener 类的一个字段。通过维护此引用,我们确保委托在钩子的整个生命周期中保持活动状态并可用于回调调用。

通过以这种方式解决线程问题,全局键盘钩子将继续可靠地捕获和处理键盘事件,即使在无情的击键情况下也是如此。

以上是为什么 C# 中的全局键盘挂钩在持续击键后停止工作?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn