SetWindowsHookEx全局键盘钩子没有捕获所有按键

时间:2009-12-30 23:47:55

标签: c# .net keyboard hook

我正在编写属于自动化系统的代码。我想添加一个键盘钩子来提前结束测试,我是通过使用SetWindowHookEx完成的。

我的代码看起来非常像这样:http://support.microsoft.com/kb/318804

这是我的SetWindowsHookEx调用:

hHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0);

现在,当我运行自动化时,自动化系统内的按键(来自SendKeys)会触发键盘挂钩方法,但是当我手动敲击键盘时,它不会被触发。

如果有帮助,我可以分享更多代码,但它是更大系统的一部分。我很确定:

  1. 我的SetWindowsHookEx不正确,或
  2. 自动化系统中的某些东西绕过我的键盘钩子(我真的不知道怎么说)。

我编写了一个测试应用程序,它使用microsoft.com的示例代码来确定我的方法是否有价值(即它有效),但是我无法将其与自动化系统集成。

对于如何确定出错的地方的任何想法都将不胜感激。

编辑:自动化工具中没有其他SetWindowsHookEx实例。我不太清楚全球键盘钩子的细微差别w.r.t.线程和桌面。如果我添加一个全局键盘钩子,它的添加位置是否重要?

2 个答案:

答案 0 :(得分:3)

George Mamaladze的文章Processing Global Mouse and Keyboard Hooks in C#如果应用程序在CodeProject中“在后台”已经存在,自2004年以来一直存在,经过多次修订,他仍然支持并更新它:据我理解,他开始他的项目是因为他无法在.NET中实现全局挂钩,这在应用程序在后台运行时有效,但后来发现你可以挂钩某些“低级”事件:formerly Q318804 : now MSDN article revised (?) that says you can hook WH_KEYBOARD_LL

也许,因为George的代码经过这么多年的C#程序员的现场测试,并且针对错误或问题进行了大量修改:他的代码中有一些可能的价值吗?在他的文章中,在版本1“常见问题解答”中,他展示的代码将使钩子应用程序具体化,而不是全局化。

上面引用的MSDN文章提到......在允许挂钩低级别事件的情况下,正如您所做的那样:

  

“调用低级别挂钩程序   在安装钩子的线程上。   低级挂钩不需要这样   钩子程序在一个实现   DLL“。

假设:线程可能与您观察的内容有关吗?

我假设您已经完成并考虑了所有细节:MSDN : LowLevelKeyboardProc Function

答案 1 :(得分:2)

回应您的评论 -

如果您只是需要测试一个键是否已关闭以退出测试,您只需在GetAsyncKeyState()上进行轮询,这将告诉您特定键是否已关闭,无论当前谁有键盘焦点。

用户必须按住一个或一组按键才能让您的轮询注意到,这意味着他们要将其按住几秒钟,或者您需要更频繁地轮询一秒钟。

但是这比全局键盘钩子要少得多。

全局钩子应该序列化通常彼此异步的内核部分,因此它们也会损害系统性能。