3

全局 Windows 挂钩必须在 DLL 中,因为挂钩将在不同进程的上下文中调用,因此挂钩过程的代码必须注入该进程。但是,有一些限制

SetWindowsHookEx可用于将 DLL 注入另一个进程。32位DLL不能注入64位进程,64位DLL不能注入32位进程。如果一个应用程序需要在其他进程中使用钩子,则需要一个 32 位应用程序调用 SetWindowsHookEx将一个 32 位 DLL 注入 32 位进程,一个 64 位应用程序调用 SetWindowsHookEx将一个 64 位 DLL 注入64 位进程。32 位和 64 位 DLL 必须具有不同的名称。

出于这个原因,我宁愿使用低级钩子WH_MOUSE_LLand WH_KEYBOARD_LL,而不是WH_MOUSEand WH_KEYBOARD。从他们的 文档中可以看出:

这个钩子在安装它的线程的上下文中被调用。通过向安装钩子的线程发送消息来进行调用。因此,安装钩子的线程必须有一个消息循环。

这使我认为这些特定的钩子程序不需要位于单独的 DLL 中,而可以直接存在于连接它们的 EXE 中。但是,文档SetWindowsHookEx说:

lpfn

[in] 指向钩子程序的指针。如果dwThreadId参数为零或指定由不同进程创建的线程的标识符,则该lpfn参数必须指向 DLL 中的挂钩过程。

没有提到两个低级挂钩的明确例外。

我见过几个使用低级钩子的 .NET 应用程序,它们的钩子过程没有放在单独的 DLL 中。这是另一个暗示这是可以接受的。但是,由于文档禁止这样做,我自己有点害怕这样做。

如果我不使用 DLL 并且只是将这些低级挂钩程序直接放入我的 EXE 中,是否有人预见到任何麻烦?

编辑:对于赏金,我想要一个明确的“是的,这没关系,因为......”或“不,这可能会出错,因为......”。

4

5 回答 5

4

事实证明,这实际上是在文档中。虽然不是在SetWindowsHookEx和朋友的文档中,而是在一篇.NET知识库文章中

在安装钩子的线程上调用低级钩子程序。低级挂钩不需要在 DLL 中实现挂钩过程。

于 2010-03-10T18:42:37.673 回答
3

dll 规则中的全局挂钩函数有一个例外。低级鼠标和键盘挂钩在调用进程的上下文中执行,而不是在被挂钩的进程中执行(在内部,Windows 通过 Windows 消息通知您的挂钩)。因此,钩子代码不会在任意进程中执行,并且可以用 .Net 编写。有关示例,请参见http://www.codeproject.com/KB/cs/CSLLKeyboardHook.aspx 。

对于其他挂钩,您确实需要调用 32 位版本的 SetWindowsHookEx 并在 32 位进程中传递挂钩函数,并调用 64 位版本的 SetWindowsHookEx 并在 64 位进程中传递挂钩函数。

于 2009-11-02T18:52:25.427 回答
1

全局挂钩,无论是低级别还是高级别,都必须位于可以加载到每个进程中的单独 DLL 中。您引用的文档非常清楚,如果有适用于低级挂钩的异常,该文档也会这么说。

于 2009-10-28T19:31:53.023 回答
0

经验法则:当文档说不做某事时,通常有一个很好的理由。虽然它在某些情况下可能有效,但它有效的事实可能是一个实现细节,并且可能会发生变化。如果发生这种情况,那么如果修改了实现,您的代码将被破坏。

于 2009-11-02T18:56:07.010 回答
0

编辑:我收回我之前的回答。事实证明 WH_MOUSE_LL 和 WH_KEYBOARD_LL 是关于全局挂钩的常规规则的例外:

传递给 SetWindowsHookEx 的 HINSTANCE 是做什么用的?

于 2009-11-03T16:10:58.193 回答