2010-12-18 95 views
9

不幸的是,MSDN不够清楚。我正在编写一个使用全局钩子的程序,而且我担心如果程序异常终止(崩溃,被用户杀死等)会发生什么。如何确保在异常终止时调用UnhookWindowsHookEx?

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

  2. 如果没有,是否可以在另一个进程中调用UnhookWindowsHookEx()来释放钩子? (如果它检测到安装程序进程已死亡,我正在考虑在挂钩线程中执行此操作。)

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

  4. 我在MSDN上读过UnhookWindowsHookEx()没有释放在其他进程中加载​​的dll,但没有说明dll何时被释放。 This article in CodeProject似乎暗示当第一个消息到达挂钩线程时,dll未被映射(在相应的进程中),因此它紧跟在UnhookWindowsHookEx()调用之后。这是真的吗?

谢谢。

回答

9
  1. 是的,当一个进程终止后系统会清理它 - 所有的句柄都是隐式关闭的。
  2. 不,它不是,你也不需要。
  3. (这是的,不是不,不,不,不是和不)不,
  4. 我不明白为什么在这里涉及的另一个过程中加载了一个DLL。 (编辑:我最初想到一个系统范围的钩子,如CBTProc - 如果你的钩子是每个进程可能不同)如果你正在处理像@Hans的评论中指出的链接,我们已经将自己的DLL注入到了目标进程中,然后您应该将功能卸载到您的DLL中,而不是将它与您的应用程序绑定。 (也就是说,如果将消息发送回您的应用程序在DLL内部失败,那么您的DLL应该决定卸载它自己)/编辑当一个DLL被加载到另一个进程中时,它就可以完成释放。
+3

您的观点4并不准确,全局钩子需要将具有钩子回调的DLL注入到目标进程中。解除钩子还涉及再次卸载该DLL。关键是,这是通过消息循环在进程本身内同步的。 – 2010-12-18 17:34:17

+0

@Hans:这取决于钩子的种类。系统范围挂钩不会将您的DLL注入到目标进程中。很明显,如果你已经将一个DLL注入到目标进程中,那么这个进程就是释放它的那个进程(这就是我上面说的第二句话)。 – 2010-12-18 22:06:29

+0

不,它确实不这样。复杂,很高兴这是你的答案,而不是我的:)这否则Just Works™。 – 2010-12-18 22:12:07

相关问题