如何检测在另一个进程中弹出的消息框?
Posted
技术标签:
【中文标题】如何检测在另一个进程中弹出的消息框?【英文标题】:How can I detect message boxes popping up in another process? 【发布时间】:2010-03-18 16:31:12 【问题描述】:每当(任何!)消息框(由MessageBox Function 产生)在另一个进程中显示时,我想执行一些代码。我没有启动我正在监控的进程。
我能想到三种方法:
-
安装一个全局CBT Hook 程序,它会在桌面上创建窗口时告诉我。然后,查看该窗口是否属于我正在监控的进程,以及类名是否为
#32770
(根据MSDN上的About Window Classes页面,是对话框的类名)。这可能会起作用,但它会将包含挂钩过程的 DLL 拉入桌面上的几乎每个进程,并且挂钩过程会被大量调用。闻起来像是潜在的性能问题。
尝试继承 #32770
系统窗口类(这可能吗?)并在我的自定义窗口过程中查找 WM_CREATE 消息。
拦截MessageBox Function API 调用(即使远程进程已经在运行!)并从钩子函数中调用我的代码。
到目前为止,我只知道第一个想法是可行的,但似乎真的效率低下。谁能想到比这个问题更简单的解决方案?
【问题讨论】:
尝试挂钩窗口创建,并检查窗口类。 @Pavel:这听起来像我在第一个项目符号中的建议。 @nobugz:这很有趣;它基本上是 CBT 钩子,除了 - 至少从阅读文档来看 - 不经常调用 WH_SHELL 钩子(仅适用于顶层无主窗口)。我想知道 MessageBox() 窗口是否总是符合“***、无主窗口”的条件。 消息框几乎从来都不是***无主窗口。除非您将 NULL 作为 HWND 参数传递,否则消息框是拥有的。 您好 Frerich,您找到解决方案了吗?我有类似的用例并正在寻找解决方案。如果您能与我们分享,我将不胜感激。问候 VK 【参考方案1】:我想不出任何不涉及将代码注入其他进程的有效解决方案(顺便说一句,这基本上是许多类型的钩子所做的)。但是,如果您愿意走这条路,您可以拦截对 MessageBox 的调用。
花一些时间在汇编语言模式下单步执行调试器中对 MessageBox 的调用,您会发现这是通过查找表进行的间接调用(这就是导出的工作方式)。因此,如果您可以将代码放入流程中,则可以修补表格以跳转到您的代码。
请参阅http://www.codeproject.com/KB/threads/completeinject.aspx 了解如何将 dll 注入另一个进程的代码。
【讨论】:
【参考方案2】:我认为:方法 2 是不可能的。方法 1-3 需要加载到所有进程中的 dll,方法 3“更正确”。我想由于某些原因不适合按计时器搜索窗口?
【讨论】:
+1:计时器听起来像是一种合理的方法;我只是怕我不能正确地间隔。我想尽快了解消息框,但不要让系统承受明显的负载。不过,感谢您指出替代方案!【参考方案3】:我会选择第一个选项。您应该能够只为您正在监视的应用程序的主 UI 线程安装挂钩,但如果这不起作用,根据我的经验,即使是全局 CBT 挂钩也不会占用太多资源。当然,你会希望你的钩子 DLL 包含尽可能少的钩子逻辑本身以外的内容。如果您需要任何庞大的东西,请仅在您知道自己处于正确的过程中时动态链接它。
【讨论】:
+1:确实在应用程序的 UI 线程上安装 CBT 挂钩会便宜得多,但不幸的是我不知道哪个线程是 UI 线程。我想我最初可以全局安装钩子,一旦我注意到在我的受监视进程中创建了一个窗口,就确定该窗口所在的线程并将我的钩子安装在那里。以上是关于如何检测在另一个进程中弹出的消息框?的主要内容,如果未能解决你的问题,请参考以下文章