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

Posted

技术标签:

【中文标题】我可以将 LowLevelMouseProc 和 LowLevelKeyboardProc 放在主 EXE 中吗?【英文标题】:Can I put LowLevelMouseProc and LowLevelKeyboardProc in the main EXE? 【发布时间】:2009-10-28 19:20:31 【问题描述】:

全局 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。从theirdocumentation看:

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

这使我认为这些特定的挂钩过程不需要位于单独的 DLL 中,而可以直接存在于将它们挂钩的 EXE 中。然而,documentation for SetWindowsHookEx 表示:

lpfn

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

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

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

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

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

【问题讨论】:

【参考方案1】:

原来这个实际上在文档中。虽然不在SetWindowsHookEx和朋友的文档中,但是在a .NET knowledge base article。

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

【讨论】:

【参考方案2】:

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

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

【讨论】:

【参考方案3】:

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

【讨论】:

我认为你应该更仔细地阅读这个问题。如果这确实是一个要求,.NET 应用程序如何成功使用低级挂钩? 关于全局钩子的问题,AFAICT。 “有消息循环”并不意味着它不能是实现它的DLL;由于各种原因,我已经完成了几个创建消息循环的 DLL。我不知道.NET 应用程序是否可以或确实使用低级挂钩,因为我从未见过或听说过这样做的。不过,我猜想,如果他们可以并且确实在 DLL 中使用了不安全的代码来做到这一点,但正如我所说的那样,我会猜测。 :-)【参考方案4】:

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

【讨论】:

【参考方案5】:

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

What is the HINSTANCE passed to SetWindowsHookEx used for?

【讨论】:

以上是关于我可以将 LowLevelMouseProc 和 LowLevelKeyboardProc 放在主 EXE 中吗?的主要内容,如果未能解决你的问题,请参考以下文章

区分鼠标设备和低级鼠标挂钩

我可以将标准 ivars 和属性添加到 NSManagedObject 吗?

我可以同时在测试和训练数据上使用 CountVectorizer 还是需要将其拆分?

如何将表单数据和此 URL 保存到数据库中.. 我可以将文件上传到 cloudinary

我可以将数组和变量作为参数传递给 C# 中的方法吗? [复制]

我可以将活动的辅助副本服务器用于故障转移和报告/备份吗