通过互操作调用dll函数时,是否有捕获或杀死弹出窗口
本文关键字:窗口 是否 调用 互操作 dll 函数 | 更新日期: 2023-09-27 17:56:08
我正在编写一个 C# 应用程序,该应用程序调用使用非托管代码编写的 DLL 中的函数。
在大多数情况下,调用工作正常,被调用的函数返回一个整数值,指定成功或一些错误代码。但是,对于几个错误代码,DLL似乎还会弹出一个消息框,提供有关错误的更多信息。
我无法知道给定的功能调用是否会发生这种情况,并且宁愿不使用这些消息框来麻烦用户,因为有时我在批处理过程中调用此函数数千次,我宁愿不要让用户必须按"OK"对于碰巧有多少故障。
是否有任何方法可以确定在给定呼叫后显示消息框,或者通常禁用或禁止在给定呼叫期间显示任何窗口或表单?这似乎不太可能,但我想无论如何我都会问。
谢谢M先生
正如您所怀疑的那样,您将无法从尚未编写的代码中抑制弹出窗口,除非调用具有可以为您执行此操作的特定参数。消息框是否与特定错误代码相关联?
有一些程序可以监视您的计算机中的特定窗口,并在它们出现时单击它们上的按钮,当然要求用户运行它也有点负担。[编辑:乔指出,你可以在一个单独的线程上自己做这件事。也是一种选择。
在使用依赖项时,总会有权衡,您必须平衡依赖项的有用性和必要性与它可能需要您做出的妥协。
调查低级别的 Win API 调用,它们可能会为您提供解决方案。
例如,使用Spy++可以显示窗口名称,然后您可以搜索并关闭这些名称。 然后使用 WINDOWS API 标注...
using System.Runtime.InteropServices;
// Get a handle to an application window.
[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
private static extern IntPtr FindWindow(string lpClassName,
string lpWindowName);
// Activate an application window.
[DllImport("USER32.DLL")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
然后在后台线程中,编写一个查找这些窗口并关闭它们的进程。
//Some PsuedoCode, note loop should have a cancel condition!
while (true)
{
//Get a handle.
handle = FindWindow(windowClassName, windowName);
//We found the window, close it
if (handle != IntPtr.Zero)
{
//Send Close Command
SetForegroundWindow(handle);
SendKeys.SendWait("%{F4}");
}
//Wait 200ms seconds before trying again
System.Threading.Thread.Sleep(200);
}
您也许可以在应用程序中执行此类类型的黑客解决方案。
请注意,您必须将 windowClassName(s) 和 windowName(s) 存储在某种配置文件中,或者在应用程序中对它们进行硬编码。
如果认为有必要,实际上没有办法阻止任意(非托管)DLL 弹出 UI。
不过,一个丑陋的解决方法是尝试在弹出窗口后立即关闭窗口。 我会这样做的方式是
- 启动另一个线程。 它的工作是记录进程的当前活动窗口并关闭显示的任何新窗口。
- 对 DLL 进行调用
- 停止线程
这绝不是一个防弹过程,但它可以帮助您解决此问题。
从 Windows 服务内部运行此代码是否可行?
不允许服务显示 GUI(您过去可以选择允许服务显示 GUI,但 MS 已逐步淘汰此功能)。我不确定,但我认为当您从非交互式服务调用它们时,对 MessageBox() 等的调用可能会立即返回。