我可以在主EXE中放置LowLevelMouseProc和LowLevelKeyboardProc吗?

时间:2009-10-28 19:20:31

标签: winapi hook low-level

全局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_LLWH_KEYBOARD_LL,而不是WH_MOUSEWH_KEYBOARD。从their documentation

可以看出
  

此钩子在上下文中被调用   安装它的线程。电话   是通过发送消息到   安装钩子的线程。   因此,安装的线程   钩子必须有一个消息循环。

这让我认为这些特定的钩子程序不需要在一个单独的DLL中,并且可以只存在于连接它们的EXE中。但是documentation for SetWindowsHookEx说:

  

lpfn

     

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

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

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

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

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

5 个答案:

答案 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是关于全局钩子的通常规则的例外:

What is the HINSTANCE passed to SetWindowsHookEx used for?