4

我最近一直在研究低级键盘挂钩。我已经开始工作了,但我对代码有一些疑问。

我看到这里有控制台应用程序的完整代码:http: //blogs.msdn.com/b/toub/archive/2006/05/03/589423.aspx

在 Main 函数中,我看到程序员调用了一个“UnhookWindowsHookEx”DLL 函数。这个函数的目的是什么,如果它被注释掉会发生什么?(特别是不好的后果?)

编辑:

还有一件事情。为什么必须调用“Application.Run()”才能使代码正常工作?

4

3 回答 3

3
  1. 在这种特殊情况下,如果 UnhookWindowsHookEx 被注释,则不会发生任何不好的事情,因为程序无论如何都会退出。但是最好在不再需要任何资源时关闭任何资源,无论是在程序继续执行时还是在程序结束时 - 以控制资源使用。

  2. 没有 Application.Run 程序立即退出。使用 Application.Run 的第二个原因是 SetWindowsHookEx 要求 - 它需要消息循环才能工作。Application.Run 执行消息循环。按 Ctrl+C 可以停止程序。

于 2012-10-03T08:44:45.963 回答
2

调用 UnhookWindowsHookEx() 并不是绝对必要的,Windows 确实会发现您忘记这样做并且会在您的程序终止时取消挂钩。必然如此,不清理钩子会导致 Windows 挂起。不将其留给操作系统被认为是“礼貌”。

Application.Run() 调用是实现低级挂钩的程序的硬性要求。如果没有消息循环,例如使用 Console.ReadLine(),则不会对钩子进行回调。具体的 Windows 承诺是回调将在调用 SetWindowsHookEx() 的同一线程上进行。为此,Windows 以某种方式“闯入”并强制您的线程调用回调方法。它不能随意中断你的线程并强制它进行调用,这会导致可怕的重入问题。您的线程必须处于明确定义的状态,它必须处于空闲状态并且不会改变程序状态。

消息循环,特别是 GetMessage() 或 PeekMessage() winapi 函数,就是那个信号,当您的线程泵送消息循环时,它处于空闲状态并等待 Windows 告诉它做某事。它是生产者/消费者问题的通用解决方案。

于 2012-10-03T10:23:43.197 回答
2

不,这很糟糕。

本机挂钩不是与文件或进程句柄相同意义上的“句柄”。它们对于 Windows 会话是持久的,并且资源稀缺。

我尽可能地尝试调用它,但我经常被迫终止我的,因为它挂起或其他什么,并且在两打左右之后,钩子无法注册。

所有其他使用钩子的应用程序,比如一些游戏,在此之后也会失败。唯一的解决方案似乎是重新启动。

于 2013-07-22T11:36:19.403 回答