即使异常终止,如何确保调用UnhookWindowsHookEx?

Gar*_*ang 10 c++ windows winapi unhookwindowshookex

不幸的是,MSDN对它不够清楚.我正在编写一个使用全局钩子的程序,我担心如果程序异常终止(崩溃,被用户杀死等)会发生什么.

  1. 当进程终止时,Windows是否自动解除进程安装的全局挂钩?

  2. 如果没有,是否可以在另一个进程中调用UnhookWindowsHookEx()来释放钩子?(我想在钩子线程中这样做,如果它检测到安装程序进程已经死了.)

  3. 如果答案是否定,那么在安装程序进程终止时保持全局挂钩处于活动状态并不危险?处理这种情况的标准方法是什么?

  4. 我在MSDN中读到UnhookWindowsHookEx()没有释放在其他进程中加载​​的dll,但它没有说明何时释放dll.CodeProject中的这篇文章似乎暗示当第一条消息到达钩子线程时,dll未被映射(在相应的进程中),所以它就在UnhookWindowsHookEx()调用之后.这是真的吗?

谢谢.

Bil*_*eal 9

  1. 是的,当一个进程终止时系统会在它之后清理 - 所有句柄都被隐式关闭.
  2. 不,它不是,反正你也不需要.
  3. (这是肯定的,不是不,不是)
  4. 我不明白为什么在这里涉及的另一个进程中加载​​了一个DLL.(编辑:我最初想的是一个系统范围的钩子,比如CBTProc--如果你的钩子是每个进程可能有所不同)如果你正在处理类似@Hans评论中指示的链接,你注入了你自己的DLL进入目标进程,然后你应该放置功能来卸载你的DLL内的钩子,而不是将它的正确操作绑定到你的应用程序.(即如果将消息发送回您的应用程序在DLL内失败,那么您的DLL应该决定卸载它自己)/编辑当DLL被加载到另一个进程内时,由该进程来执行释放.

  • 你的观点4不准确,全局钩子需要将具有钩子回调的DLL注入到目标进程中.取消挂钩还涉及再次卸载该DLL.关键点在于它通过消息循环在进程内部进行同步. (3认同)
  • 这是一种恭维,抱歉我搞砸了。CBT 挂钩全局挂钩。它确实是系统范围的并且*确实*需要注入。嗯,根据 SetWindowsHookEx() 调用参数,指定线程不会使其成为全局线程。 (2认同)