【问题标题】:How to handle Message Boxes while using webbrowser in C#?在 C# 中使用 webbrowser 时如何处理消息框?
【发布时间】:2024-04-22 17:25:01
【问题描述】:

我正在使用 C# 的这个 webbrowswer 功能。尝试通过我的应用程序登录网站。一切正常,除了输入错误的 ID 或密码时,会弹出一个小消息框(在网页本身上设置)并阻止所有内容,直到单击“确定”。

所以问题是:有没有办法管理这个小窗口(比如阅读里面的文字)?如果真是太好了! 但是,如果没有办法做到这一点,那么有没有办法简单地让这个消息框以编程方式消失?

【问题讨论】:

  • 是否有特定的原因为什么您不使用 webbrowser 控件直接将表单发布到网络服务器?
  • 啊哈...愿意分享吗?
  • 是的,不明白为什么要使用网络浏览器控件,如果,显然,你想自动化一些东西。
  • 大声笑,我喜欢这种回应。他问埃米尔这个问题是因为,您确定没有更好的方法来访问这些详细信息/页面/数据,而不是将网络浏览器嵌入到您的应用程序中吗?这种方法容易出错,我想你可能会发现如果没有 ALLOT 黑客,你将无法对这个警报做很多事情

标签: c# browser messagebox


【解决方案1】:

这里是 Saeb 答案的精炼版本。 Saeb 的代码对我不起作用,我又添加了一个步骤来激活按钮,然后单击它。

using System;
using System.Runtime.InteropServices;

namespace IE_Automation
{
public class IEPoppupWindowClicker
{
    [DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

    [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
    private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);
    private const int BM_CLICK = 0xF5;
    private const uint WM_ACTIVATE = 0x6;
    private const int WA_ACTIVE = 1;

    public void ActivateAndClickOkButton()
    {
        // find dialog window with titlebar text of "Message from webpage"

        var hwnd = FindWindow("#32770", "Message from webpage");
        if (hwnd != IntPtr.Zero)
        {
            // find button on dialog window: classname = "Button", text = "OK"
            var btn = FindWindowEx(hwnd, IntPtr.Zero, "Button", "OK");
            if (btn != IntPtr.Zero)
            {
                // activate the button on dialog first or it may not acknowledge a click msg on first try
                SendMessage(btn, WM_ACTIVATE, WA_ACTIVE, 0);
                // send button a click message

                SendMessage(btn, BM_CLICK, 0, 0);
            }
            else
            {
                //Interaction.MsgBox("button not found!");
            }
        }
        else
        {
            //Interaction.MsgBox("window not found!");
        }

    }
}
}

【讨论】:

    【解决方案2】:

    您可以通过从 user32.dll 导入一些窗口函数并通过类名和窗口名获取消息框对话框的句柄来“管理”消息框对话框。例如点击它的确定按钮:

    public class Foo
    {
        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
    
        [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
    
    
        private void ClickOKButton()
        {
            IntPtr hwnd = FindWindow("#32770", "Message from webpage");
            hwnd = FindWindowEx(hwnd, IntPtr.Zero, "Button", "OK");
            uint message = 0xf5;
            SendMessage(hwnd, message, IntPtr.Zero, IntPtr.Zero);
        }
    }
    

    Some reading material from MSDN.

    【讨论】:

    • 哇!好人!它工作得很好!但是如何阅读上下文呢? (比如看“登录不正确”还是“密码不正确”?
    • @Emil,见WM_GETTEXT
    【解决方案3】:

    从 Sires anwser 复制粘贴:https://*.com/a/251524/954225

    private void InjectAlertBlocker() {
        HtmlElement head = webBrowser1.Document.GetElementsByTagName("head")[0];
        HtmlElement scriptEl = webBrowser1.Document.CreateElement("script");
        IHTMLScriptElement element = (IHTMLScriptElement)scriptEl.DomElement;
        string alertBlocker = "window.alert = function () { }";
        element.text = alertBlocker;
        head.AppendChild(scriptEl);
    }
    

    【讨论】: