C# Webbrowser 以编程方式关闭 JS 确认框 [英] C# Webbrowser Programmatically Close JS Confirm Box

查看:30
本文介绍了C# Webbrowser 以编程方式关闭 JS 确认框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用 webbrowser 控件时,我需要以编程方式自动关闭 javascript 确认框.

while using webbrowser control, I need to programmatically auto close a javascript confirm box.

我使用了以下 user32.dll 方法,它在基于英语的操作系统上运行良好.

I used below user32.dll approach and it is working fine on OS which are based english language.

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

但如果计算机运行非英文操作系统,则无法正常工作,因为我在上述方法调用中使用OK"作为文本.

But if the computer running non-english OS, it is not working fine as I am using "OK" as text in above method call.

我认为可行的一种方法是我应该检测操作系统语言,然后使用翻译的OK"文本来使用上述方法.这里我的问题是我可以更改当前线程的语言和浏览器控件,以便它以英语显示确认框吗?在我看来,这将是一个简单快捷的解决方案.

One approach which I suppose can work is I should detect OS language and then use translated "OK" text to use above method. Here my question is can I change language of the current thread and so webbrowser control so that it show confirm box in English language? This way it would be easy and fast solution in my opinion.

请提出您的解决方案.提前致谢.

Please suggest your solutions. Thanks in advance.

我在我的代码中使用了类似的方法,但是这些解决方案仅适用于英语语言软件.我实际上正在寻找一些可以在非英语操作系统上运行的通用解决方案.

I am using similar approach in my code however these solutions are working for English language software only. I am actually looking for some generic solution that can run on non-english OS as well.

推荐答案

一种可能的解决方案是注入并立即调用劫持原始确认函数的 Javascript 函数:

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

这是带有标准 WPF WebBrowser 控件的 WPF 应用程序示例,我非常有信心我在这里所做的一切都可以调整以适应 WinForm 控件(因为底层的 ActiveX 是相同的).我有一个用作 WebBrowser 适配器的 UserControl,这里是 XAML:

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>

首先,在WebBrowserAdapter类中,需要一个方法在当前HTML文档中注入一个javascript函数:

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

然后在需要时调用 InjectScript,每当文档完成加载时:

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

在这里我导航到 http://localhost:9080/console/page.html,这是在我的系统上托管的测试页面.这在这个简单的场景中效果很好.如果您发现这适用于您,您可能需要稍微调整一下代码.为了编译代码,你必须在项目引用中添加Microsoft.mshtml

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

WinForm 版本

要使其工作,您必须在应用程序中使用 IE 11 引擎.按照此处的说明进行设置

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

我刚刚尝试了一个 WinForm 版本,它可以进行一些细微的更改.以下是将 WebBrowser 控件作为其子项之一的表单的代码:

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

这篇关于C# Webbrowser 以编程方式关闭 JS 确认框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆