全局Windows挂钩必须位于DLL中,因为挂钩将在不同进程的上下文中调用,因此必须将挂钩过程的代码注入到该进程中。但是,有limitations:
SetWindowsHookEx
可用于注射 一个DLL进入另一个进程。一个32位 DLL无法注入64位 进程,一个64位DLL不能 注入32位进程。如果 应用程序需要使用钩子 在其他过程中,它是必需的 一个32位的应用程序调用SetWindowsHookEx
注入32位 DLL进入32位进程,和 64位应用程序调用SetWindowsHookEx
注入64位 DLL进入64位进程。 32位 和64位DLL必须有不同 名。
出于这个原因,我宁愿使用低级别的钩子WH_MOUSE_LL
和WH_KEYBOARD_LL
,而不是WH_MOUSE
和WH_KEYBOARD
。从their documentation:
此钩子在上下文中被调用 安装它的线程。电话 是通过发送消息到 安装钩子的线程。 因此,安装的线程 钩子必须有一个消息循环。
这让我认为这些特定的钩子程序不需要在一个单独的DLL中,并且可以只存在于连接它们的EXE中。但是documentation for SetWindowsHookEx
说:
lpfn
[in]指向钩子程序的指针。如果是
dwThreadId
参数 为零或指定标识符 由不同的线程创建的线程 进程,lpfn
参数必须指向 到DLL中的钩子程序。
没有提到两个低级别钩子的明确例外。
我见过几个使用低级钩子的.NET应用程序,而没有在单独的DLL中使用它们的钩子程序。这是另一个提示,这是可以接受的。但是,由于文档禁止它,我自己有点害怕这样做。
如果我不使用DLL并且只是将这些低级钩子程序直接放入我的EXE中,是否有人预见到任何问题?
编辑:对于赏金,我想要一个明确的“是的,这没关系,因为......”或“不,这可能会出错,因为......”。
答案 0 :(得分:3)
dll规则中的全局挂钩函数有一个例外。低级鼠标和键盘挂钩在调用进程的上下文中执行,而不是挂钩的进程(在内部,Windows通过Windows消息通知您的挂钩)。因此,钩子代码不会在任意进程中执行,并且可以用.Net编写。有关示例,请参阅http://www.codeproject.com/KB/cs/CSLLKeyboardHook.aspx。
对于其他挂钩,您需要调用32位版本的SetWindowsHookEx并在32位进程中传递钩子函数并调用64位版本的SetWindowsHookEx并在64位进程中传递钩子函数。
答案 1 :(得分:2)
事实证明, 实际上是在文档中。虽然不在SetWindowsHookEx
和朋友的文档中,但在a .NET knowledge base article。
在安装挂钩的线程上调用低级挂钩过程。低级挂钩不要求在DLL中实现挂钩过程。
答案 2 :(得分:1)
全局钩子,无论是低级别还是高级别,都必须位于可以加载到每个进程的单独DLL中。您引用的文档非常清楚,如果有一个异常应用于低级别的钩子,那么文档也会这样说。
答案 3 :(得分:0)
答案 4 :(得分:0)
编辑:我收回我之前的回答。事实证明,WH_MOUSE_LL和WH_KEYBOARD_LL是关于全局钩子的通常规则的例外: