尝试从C#在ActiveX WebBrowser中设置/获取JavaScript变量
我们有一个Windows应用程序,其中包含ActiveX WebBrowser控件。作为此应用程序常规操作的一部分,会对ActiveX WebBrowser控件显示的页面进行修改。这些修改的一部分涉及在要加载到ActiveX WebBrowser的网页中设置JavaScript变量。
我们需要在C中初始化此变量(最初,VB6代码正在初始化该值)。此变量的值是COM可见的类对象。
但是,为简单起见,我们将问题简化为设置字符串值。我们的原始页面涉及框架之类的东西,但是在类似的页面中也会发生相同的问题:
<HTML> <HEAD> <TITLE>Test</TITLE> <SCRIPT type="text/javascript"> var field = 'hello world'; </SCRIPT> </HEAD> <BODY> <input type="button" value="See field" onclick="javascript:alert(field);"/> </BODY> </HTML>
我们要访问字段变量并为其分配一个值。在VB6中,此代码非常简单:
doc.Script.field = 'newValue'
但是,在Cwe中,不得不采用其他技巧,例如:
Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateSet(Script, null, "field",new object[] { "newValue"},null, null);
该页面的重点是测试我们的变量是否由C#正确分配。单击该按钮应产生C#注入的任何新值。因此,例如,单击页面上的按钮,我们将显示一个警报:" newValue"。
第一次可以使用,但是如果我们重新加载页面,则无法使用。在后续调用中,我们无法设置变量" field"的值。
以前有没有人做过这种类型的手术?
解决方案
我们通常使用的方法是在页面上添加一个隐藏的文本输入框(ASP.Net控件版本)。这样,我们可以轻松地在Ccodebehind中设置其值,并在客户端JavaScript中读取该值(当然,反之亦然)。
这两篇文章帮助我们找到了解决问题的方法。他们概述了需要了解的基本知识:
使用C#的Microsoft Web浏览器自动化
使用MSHTML高级托管接口
因此,我们实现了DocHostUIHandler接口,该接口允许我们设置UIHandler,从而允许我们从Javascript引用方法。
如果使用webBrowser控件,则可以将cobject分配给
objectForScripting属性
http://msdn.microsoft.com/zh-CN/library/system.windows.forms.webbrowser.objectforscripting.aspx
之后,我们可以在JavaScript中使用window.external与javascript中的cobject进行交互
如果由于某种原因使用activeX版本,则可以传递javascript:url以编程方式设置变量,或者可以使用webservice /数据库/文件或者仅使用建议的方法来同步脚本。
我认为我们正在寻找的是Javascript中的eval()
方法。我们可以像这样从C调用它:
webBrowser1.Document.InvokeScript("eval", new String[] {"1 + 2"});
该代码将评估" 1 + 2"并返回" 3"。我想如果你把
InvokeScript("eval", new String[] {"varName = 3"})
如果该变量在文件中全局可见,则将其分配给3.