如何在使用C#中的WebBrowser时处理消息框?

4
我正在使用C#的WebBrowser功能。尝试通过我的应用程序登录网站。一切都很顺利,除了当输入错误的ID或密码时,会弹出一个小消息框(设置在网页本身上),它会阻止一切直到点击“确定”。
所以问题是:有没有可能管理这个小窗口(比如读取里面的文本)?如果可以那太好了!但如果无法做到这一点,那么有没有办法通过编程使这个消息框消失?

你为什么不直接将表单POST到Web服务器而不使用Web浏览器控件?是否有特定的原因? - Daniel Hilgarth
啊哈...你愿意分享吗? - Daniel Hilgarth
1
是的,我也不明白为什么你要使用WebBrowser控件,如果你显然想自动化某些东西。 - squelos
1
哈哈,我喜欢那个回答。他问这个问题是因为,你确定没有更好的方法来访问这些详细信息/页面/数据而不是将Web浏览器嵌入到应用程序中吗?这种方法容易出现错误,我认为你可能会发现,如果没有大量的技巧,你将无法对这个警报进行太多修改。 - Maxim Gershkovich
3个回答

9
您可以通过从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
@Emil,请查看WM_GETTEXT - Saeb Amini

2

从Sires的回答中复制粘贴:https://dev59.com/fHVD5IYBdhLWcg3wHn6d#251524

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);
}

0

这是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!");
        }

    }
}
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接