我最近一直在研究低级键盘挂钩。我已经开始工作,但我对代码有一些疑问。
我在这里看到有一个完整的控制台应用程序代码: http://blogs.msdn.com/b/toub/archive/2006/05/03/589423.aspx
在Main函数中,我看到程序员称为“UnhookWindowsHookEx”DLL函数。这个函数的目的是什么?如果它被注释掉会发生什么? (特别是糟糕的后果?)
编辑:
还有一件事。为什么必须调用“Application.Run()”才能使代码生效?
答案 0 :(得分:2)
在这种特殊情况下,如果注释了UnhookWindowsHookEx,则不会发生任何不良情况,因为无论如何程序都会退出。但是,当程序继续执行时,以及程序结束时,不再需要关闭任何资源是个好主意 - 保持资源使用在控制之下。
没有Application.Run程序立即退出。使用Application.Run的第二个原因是SetWindowsHookEx要求 - 它需要消息循环才能工作。 Application.Run执行消息循环。按Ctrl + C可以停止程序。
答案 1 :(得分:2)
没有必要调用UnhookWindowsHookEx(),Windows确实发现您忘记这样做并且在程序终止时将取消挂钩。必须如此,不清理挂钩会导致Windows挂起。不把它留给操作系统被认为是“礼貌”。
Application.Run()调用是实现低级别钩子的程序的硬性要求。如果没有消息循环,比如说使用Console.ReadLine(),则不会对钩子进行回调。具体的Windows承诺是回调将在调用SetWindowsHookEx()的同一个线程上进行。为此,Windows以某种方式“中断”并强制您的线程调用回调方法。它不能随意中断你的线程并强制它进行调用,这会导致可怕的重入问题。你的线程必须处于一个定义良好的状态,它必须是空闲的,而不是改变程序状态。
消息循环,特别是GetMessage()或PeekMessage()winapi函数,就是那个信号,当你的线程泵出消息循环然后它处于空闲状态并等待Windows告诉它做某事。它是producer/consumer problem的通用解决方案。
答案 2 :(得分:1)
不,这很糟糕。
我经常终止我正在开发的程序,因为它挂起了什么东西,经过二十几次钩子无法注册。
所有其他使用钩子的应用程序,如fps游戏,现在也失败了。唯一的解决方案似乎是重启。