繁体   English   中英

全局键盘挂钩会减慢计算机速度

[英]global keyboard hook slowing down computer

我正在使用本文中的代码:

private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYDOWN = 0x0100;
private static LowLevelKeyboardProc _proc = HookCallback;
private static IntPtr _hookID = IntPtr.Zero;

public static void Main()
{
    _hookID = SetHook(_proc);
    //Application.Run();
    //UnhookWindowsHookEx(_hookID);
}

private 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);
    }
}

private delegate IntPtr LowLevelKeyboardProc(
    int nCode, IntPtr wParam, IntPtr lParam);

private static IntPtr HookCallback(
    int nCode, IntPtr wParam, IntPtr lParam)
{
    if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
    {
        int vkCode = Marshal.ReadInt32(lParam);
        ***custom code***
    }
    return CallNextHookEx(_hookID, nCode, wParam, lParam);
}

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook,
    LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
    IntPtr wParam, IntPtr lParam);

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);

稍作修改,但有时当我按几次击键速度太快时,计算机就会“变慢”一点,并变得有些“松弛”。

因此,当它异步触发事件HookCallback时,有时会有些滞后,但是我猜想它在此方法“ HookCallback”中的代码使它滞后,还是自己对其进行了挂钩? 我有一个关于每次输入“ HookCallback”时创建一个新线程的想法,这可能会有所帮助,但是我是否想每次按一个键就启动一个新线程? 我已经收到一个异步调用,所以我不知道是否应该启动另一个线程。

所以我的问题很简单,它在何处以及为什么会降低计算机的速度,是将其自身钩住还是将其自定义? 还是应该将自定义代码放在其他线程中?

而且我还有另一个问题,有时在几次按键之后就没有调用“ HookCallback”,好像我已经“取消”了该事件一样,它根本无法捕获任何击键。 除非手动进行操作,否则如何确保它永远不会取消该事件?

谢谢。

我花了很多时间做键盘挂钩,因此以下只是我自己的经验。 挂钩需要高效。 几年前,我编写了一个小型POS应用程序,该应用程序必须捕获击键。 它是用C#编写的,将输入的速度减慢到变得引人注意的程度。 经过许多头痛之后,我终于意识到,巨大的滞后来自于从本机代码到托管代码的转换。 我用C ++(本机)重新编写了钩子代码的小片段,并看到了我认为“足够好”的改进。

只要记住,速度完全取决于代码处理它所花费的时间。 尽最大努力提高效率。

关于“摘机”问题还有另一个因素。 如果您的低级全局挂钩代码无法在一定时间内完成,则操作系统会在不通知您的情况下自动删除您的挂钩。 因此,使您的代码尽可能快地运行

干杯

我有相同的症状,但事实证明我的问题是由于Thread.Sleep();引起的。 我最近将应用程序从控制台更改为Windows应用程序。 我的代码是:

static void Main( string[] args )
{
    hook_keys();
    AppDomain.CurrentDomain.ProcessExit += CurrentDomainOnProcessExit;
    while (true) { System.Threading.Thread.Sleep( new TimeSpan(0,10,0) ); }
}
private static void CurrentDomainOnProcessExit(object sender, EventArgs eventArgs )
{
    unhook_keys();
}

即使我每次使用键盘时,钩子所做的全部工作就是增加全局变量,这也会使Windows的运行速度令人难以置信 当我将其更改为以下内容时,滞后问题得到解决:

static void Main( string[] args )
{
    hook_keys();
    var application = new Application();
    application.Run();
    unhook_keys();
}

如果您只想捕获应用程序中的击键,那么事情就可以更快了。 使用WH_KEYBOARD而不是WH_KEYBOARD_LL ,这将使性能显着提高。

private const int WH_KEYBOARD = 2;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM