C# Webbrowser 以编程方式关闭 JS 确认框
C# Webbrowser Programmatically Close JS Confirm Box
在使用网络浏览器控件时,我需要以编程方式自动关闭 javascript 确认框。
我使用了下面的 user32.dll 方法,它在基于英语的 OS 上运行良好。
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
但是如果计算机 运行 宁非英语 OS,它不能正常工作,因为我在上面的方法调用中使用 "OK" 作为文本。
我认为可行的一种方法是我应该检测 OS 语言,然后使用翻译的 "OK" 文本来使用上述方法。
这里我的问题是我可以更改当前线程的语言和 webbrowser 控件,以便它以英语显示确认框吗?在我看来,这种方式将是简单快捷的解决方案。
请提出您的解决方案。提前致谢。
我在我的代码中使用了类似的方法,但是这些解决方案仅适用于英语软件。我实际上正在寻找一些通用的解决方案,它也可以 运行 在非英语 OS 上。
一个可能的解决方案是注入并立即调用劫持原始确认函数的Javascript函数:
function hijackConfirm(){
alert('yep!');
window.oldConfirm = window.confirm;
window.confirm = function(){ return true };
}
这是带有标准 WPF WebBrowser 控件的 WPF 应用程序示例,我非常有信心可以调整我在这里所做的一切以适应 WinForm 控件(因为底层 ActiveX 是相同的)。
我有一个用作 WebBrowser 适配器的 UserControl,这里是 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
class中,你需要一个方法在当前HTML文档中注入一个javascript函数:
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
,每当文档完成加载时:
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
编辑:WinForm 版本
要使其正常工作,您必须在应用程序中使用 IE 11 引擎。按照找到的说明 here 进行设置
我刚刚尝试了它的一个 WinForm 版本,它经过一些小的改动就可以工作。以下是将 WebBrowser 控件作为其子控件之一的窗体的代码:
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);
}
}
在使用网络浏览器控件时,我需要以编程方式自动关闭 javascript 确认框。
我使用了下面的 user32.dll 方法,它在基于英语的 OS 上运行良好。
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
但是如果计算机 运行 宁非英语 OS,它不能正常工作,因为我在上面的方法调用中使用 "OK" 作为文本。
我认为可行的一种方法是我应该检测 OS 语言,然后使用翻译的 "OK" 文本来使用上述方法。 这里我的问题是我可以更改当前线程的语言和 webbrowser 控件,以便它以英语显示确认框吗?在我看来,这种方式将是简单快捷的解决方案。
请提出您的解决方案。提前致谢。
我在我的代码中使用了类似的方法,但是这些解决方案仅适用于英语软件。我实际上正在寻找一些通用的解决方案,它也可以 运行 在非英语 OS 上。
一个可能的解决方案是注入并立即调用劫持原始确认函数的Javascript函数:
function hijackConfirm(){
alert('yep!');
window.oldConfirm = window.confirm;
window.confirm = function(){ return true };
}
这是带有标准 WPF WebBrowser 控件的 WPF 应用程序示例,我非常有信心可以调整我在这里所做的一切以适应 WinForm 控件(因为底层 ActiveX 是相同的)。 我有一个用作 WebBrowser 适配器的 UserControl,这里是 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
class中,你需要一个方法在当前HTML文档中注入一个javascript函数:
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
,每当文档完成加载时:
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
编辑:WinForm 版本
要使其正常工作,您必须在应用程序中使用 IE 11 引擎。按照找到的说明 here 进行设置
我刚刚尝试了它的一个 WinForm 版本,它经过一些小的改动就可以工作。以下是将 WebBrowser 控件作为其子控件之一的窗体的代码:
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);
}
}