通过互操作调用dll函数时,是否有捕获或杀死弹出窗口

本文关键字:窗口 是否 调用 互操作 dll 函数 | 更新日期: 2023-09-27 17:56:08

我正在编写一个 C# 应用程序,该应用程序调用使用非托管代码编写的 DLL 中的函数。

在大多数情况下,调用

工作正常,被调用的函数返回一个整数值,指定成功或一些错误代码。但是,对于几个错误代码,DLL似乎还会弹出一个消息框,提供有关错误的更多信息。

我无法知道给定的功能调用是否会发生这种情况,并且宁愿不使用这些消息框来麻烦用户,因为有时我在批处理过程中调用此函数数千次,我宁愿不要让用户必须按"OK"对于碰巧有多少故障。

是否有任何方法可以确定在给定呼叫后显示消息框,或者通常禁用或禁止在给定呼叫期间显示任何窗口或表单?这似乎不太可能,但我想无论如何我都会问。

谢谢M先生

通过互操作调用dll函数时,是否有捕获或杀死弹出窗口

正如您所怀疑的那样,您将无法从尚未编写的代码中抑制弹出窗口,除非调用具有可以为您执行此操作的特定参数。消息框是否与特定错误代码相关联?

有一些程序可以监视您的计算机中的特定窗口,并在它们出现时单击它们上的按钮,当然要求用户运行它也有点负担。[编辑:乔指出,你可以在一个单独的线程上自己做这件事。也是一种选择。

在使用依赖项时,总会有权衡,您必须平衡依赖项的有用性和必要性与它可能需要您做出的妥协。

调查低级别的 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() 等的调用可能会立即返回。