WinForms – 如何从WebBrowser控件中执行C#应用程序代码?

我有一个包含Web浏览器控件的表单。 此浏览器控件将从磁盘加载一些HTML并显示它。 我希望能够在我的表单中的HTML访问C#代码中有一个按钮。

例如,HTML中的按钮可能会调用窗体上的Close()方法。

目标平台:C#和Windows Forms(任何版本)

我在过去的几个应用程序中已经实现了这一点,具体如下:(注意:下面的示例不是生产就绪的,应该仅用作指南)。

首先创建一个普通的.NET类(public),其中包含您希望从Web浏览器控件中运行的Javasvcipt调用的公共方法。

最重要的是,它必须使用System.Runtime.InteropServices命名空间中的ComVisible(true)]属性进行修饰(IE中的Javascript基于COM)。 它可以被称为任何东西,我称之为“外部”以使事情更清晰。

using System.Runtime.InteropServices; [ComVisible(true)] public class External { private static MainWindow m_mainWindow = null; public External(MainWindow mainWindow) { m_mainWindow = mainWindow; } public void CloseApplication() { m_mainWindow.Close(); } public string CurrentDate(string format) { return DateTime.Now.ToString(format); } } 

接下来,在包含Web浏览器控件的.NET表单中创建COMVisible类的实例,然后将Web浏览器控件ObjectForScripting设置为该实例:

  private void MainWindow_Load(object sender, EventArgs e) { m_external = new External(this); browserControl.ObjectForScripting = m_external; } 

最后,在Web浏览器控件中运行的Javascript中,您可以通过window.external对象访问.NET方法。 在这种情况下,window.external实际引用(间接通过COM interop包装器)上面创建的“External”对象:

 // Javascript code function CloseButton_Click() { if (window.external) { window.external.CloseApplication(); } } 

请注意,从Javascript到.NET的调用将通过COM互操作层,因此必须查询默认接口,编组参数等。 换句话说,它可能相对较慢,如果您打算例如在循环内进行多次调用,那么请进行一些性能测试。

此外,仅供将来参考,从.NET调用Javascript代码更简单,只需使用Document.InvokeScript方法:

  browserControl.Document.InvokeScript("jScriptFunction", new object[] { "param1", 2, "param2" }); 

我在VB6中做了什么:

您所要做的就是为WebBrowser的Navigating事件添加一个事件处理程序。

在浏览器导航到下一页之前会触发此事件。 它允许您中断进程并执行任何操作,包括取消导航和调用代码。

很容易使用。 我遇到的唯一警告是你无法查看PostData – 请看我的问题: PostData问题

这是一些示例代码:

  private void MyMethod() { // do something } private void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e) { MyMethod(); e.Cancel = true; } 

这是可能的,但我还没有在.NET中完成它。 几年前,我有一个托管Web浏览器控件(ActiveX)的C ++应用程序。 从控件中的HTML中,可以将“out”调用到ActiveX控件并使其执行操作。

尽管HTML DOM / JavaScript不了解C#,但在.NET中应该是可能的。 但是,如果将.NETfunction包装在COM对象中,则应该能够调用COM / ActiveX对象上的方法,这些方法将反过来调用您的C#代码。

希望这可以帮助。

几年前我做过这个,并在这里写博客:

http://matthewskelton.wordpress.com/2007/04/21/calling-javascript-from-c/

具体来说,您可以使用Type.InvokeMember()从C#调用JavaScript。