【问题标题】:Block a Processes Child Window?阻止进程子窗口?
【发布时间】:2011-05-22 07:02:02
【问题描述】:

我正在 C# .NET 中启动一个进程,由于某种原因,它在最初启动时会打开一个消息框。我需要从我的应用程序中找到某种方法来阻止此消息框被打开,或者基本上从我的代码中“单击”消息框上的“确定”按钮。

当我们将消息框作为服务运行时,消息框会导致进程挂起,因此我现在需要找到某种方法来阻止该框永远打开或直接从我的代码中关闭它(选择确定)。

我一直在查看一些 Win32 API 示例,但我以前从未使用过它,它看起来有点奇怪。任何建议都会很棒!

编辑

这里提供了一个批处理文件,作为解决该问题的方法。但是,如果可能的话,我更希望它运行一个可执行文件。解释是使用 -supw 参数(在服务器上设置密码)会导致此消息框弹出。这个批处理文件已经过测试并且可以工作,但它需要您创建一个重复的可执行文件 (murmur2.exe),它是 ghetto。

set /p VAR= < superadmin.txt
start murmur2.exe -supw %var%
ping 0.0.0.0 -n 3 > NUL
tskill murmur2
murmur.exe

【问题讨论】:

  • 我假设您生成的应用无法更改?
  • 并非如此。它是开源的,但它有一个圣经长度的依赖项列表。
  • 它显然不是为从服务运行而设计的。您需要将您的应用程序从服务更改为用户模式应用程序。服务无法显示 UI,当服务尝试显示消息框时,它会崩溃。
  • @Cody 我在想象吗?我确定我记得默认选项被采用...也许那是一个特定的上下文。
  • @Marc:我相信如果你用MB_SERVICE_NOTIFICATION 标志调用MessageBox,你就会得到向后兼容的黑客攻击。如果此处调用的应用程序并非设计为从服务运行,即使在早期版本的 Windows 下,也不太可能指定该标志。我不确定没有它会发生什么,但我绝对记得看到报告说它会挂起进程。

标签: c# .net winapi windows-services process


【解决方案1】:

PostMessage(FindWindow("#32770",*Title of the message box*),WM_CLOSE,NULL,NULL);

因为可能(机会非常渺茫)会同时打开同一个类名和同一个标题的同一个窗口,所以这不是一种防失败的方法。然而,替代方案只是矫枉过正。如果你真的想让它证明失败,你必须调用EnumWindows来枚举所有顶级窗口,然后对于每个窗口,调用GetWindowThreadProcessId并将窗口的进程ID与你启动的进程ID进行比较。如果它们相等,您可以调用GetClassName 和GetWindowText 来比较类名(对于常见对话框,始终为“#32770”)和消息框的标题,以验证您是否正在尝试关闭正确的窗口.完成后,您可以使用找到的 hWnd 使用 WM_CLOSE 调用 PostMessage。

【讨论】:

  • 您需要等到创建窗口后才能发布消息
  • 一般来说,这是可行的。但是,当尝试生成消息框的进程作为服务运行时,它将不起作用。该窗口永远不会打开,因为服务无法显示 UI。而且由于它从未打开过,它没有获得窗口句柄,并且您无法向它发送关闭消息。
  • @David Heffernan:在短时间内简单调用 FindWindow 不会有什么坏处。
  • @Cody Gray。哎呀。我想没有完全阅读这个问题。我同意您在评论中所说的:它不能将 Win32 GUI 程序作为服务运行。但是,很明显用户正在看到消息框,并且以一种或另一种方式,因此程序正在作为常规进程运行。对此唯一可能的解释是服务本身又创建了另一个进程(使用CreateProcessAsUser 或其他东西)。任何人,在任何情况下,这种方法都应该有效。
  • 不知道哪里清楚。他说当应用程序不作为服务运行时会出现消息框,这是有道理的。但是他没有说当进程作为服务运行时会出现消息框,他只是说它会导致进程挂起。你可能对CreateProcessAsUser有一些运气,但我持怀疑态度。
猜你喜欢
  • 1970-01-01
  • 2015-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-24
相关资源
最近更新 更多