C# Webbrowser Programmatically Close JS Confirm Box

北城余情 提交于 2019-12-08 18:12:28

A possible solution consists in injecting and immediately calling a Javascript function that hijacks the original confirm function:

function hijackConfirm(){
    alert('yep!');
    window.oldConfirm = window.confirm;
    window.confirm = function(){ return true };
}

This is an example in WPF application with the standard WPF WebBrowser control, I'm quite confident that everything I do here can be adjusted to fit the WinForm control (since the underlying ActiveX is the same). I have a UserControl that acts as an adapter of the WebBrowser, here is the XAML:

<UserControl x:Class="WebBrowserExample.WebBrowserAdapter"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <WebBrowser x:Name="WebBrowserControl"></WebBrowser>
    </Grid>
</UserControl>

First, in the WebBrowserAdapter class, you need a method to inject a javascript function in the current HTML document:

public void InjectScript(String scriptText)
        {
            HTMLDocument htmlDocument = (HTMLDocument)WebBrowserControl.Document;

            var headElements = htmlDocument.getElementsByTagName("head");
            if (headElements.length == 0)
            {
                throw new IndexOutOfRangeException("No element with tag 'head' has been found in the document");
            }
            var headElement = headElements.item(0);

            IHTMLScriptElement script = (IHTMLScriptElement)htmlDocument.createElement("script");
            script.text = scriptText;
            headElement.AppendChild(script);
        }

then you call InjectScript, when needed, whenever a document completes to load:

void WebBrowserAdapter_Loaded(object sender, RoutedEventArgs e)
        {
            WebBrowserControl.LoadCompleted += WebBrowserControl_LoadCompleted;
            WebBrowserControl.Navigate("http://localhost:9080/console/page.html");
        }

        void WebBrowserControl_LoadCompleted(object sender, NavigationEventArgs e)
        {
            //HookHTMLElements();
            String script = 
@" function hijackConfirm(){
    alert('yep!');
    window.oldConfirm = window.confirm;
    window.confirm = function(){ return true };
}";
            InjectScript(script);
            WebBrowserControl.InvokeScript("hijackConfirm");
        }

Here I navigate to http://localhost:9080/console/page.html, which is a test page hosted on my system. This works well in this simple scenario. If you find this could apply to you, you may need to tweak a little bit the code. In order to compile the code, you have to add Microsoft.mshtml in the project references

EDIT: WinForm version

To make it work, you have to use the IE 11 engine in your application. Follow the instructions found here to set it

I just tried a WinForm version of this and it works with some minor changes. Here is the code of a form that has a WebBrowser control as one of its children:

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.Load += Form1_Load;
        }

        void Form1_Load(object sender, EventArgs e)
        {
            webBrowserControl.Navigate("file:///C:/Temp/page.html");
            webBrowserControl.Navigated += webBrowserControl_Navigated;
        }

        void webBrowserControl_Navigated(object sender, WebBrowserNavigatedEventArgs e)
        {
            InjectConfirmHijack();
        }

        private void InjectConfirmHijack()
        {
            String script =
@" function hijackConfirm(){
    alert('yep!');
    window.oldConfirm = window.confirm;
    window.confirm = function(){ return true };
}";
            InjectScript(script);
            webBrowserControl.Document.InvokeScript("hijackConfirm");
        }

        public void InjectScript(String scriptText)
        {
            //mshtml.HTMLDocument htmlDocument = (mshtml.IHTMLDocument) webBrowserControl.Document.get;

            var headElements = webBrowserControl.Document.GetElementsByTagName("head");
            if (headElements.Count == 0)
            {
                throw new IndexOutOfRangeException("No element with tag 'head' has been found in the document");
            }
            var headElement = headElements[0];

            var script = webBrowserControl.Document.CreateElement("script");
            script.InnerHtml = scriptText;
            headElement.AppendChild(script);
        }
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!