从vb.net访问JavaScript对象

时间:2012-08-14 16:19:36

标签: vb.net mshtml dom marshalbyrefobject comobject

我正在开发一个vb.net应用程序,该应用程序与(第三方提供的)Web应用程序交互以提供其他功能(例如,删除菜单项,从页面中提取信息等)。 Web应用程序完全由javascript驱动,但托管在asp.net中,仅用于Internet Explorer。

我正在尝试从javascript对象中读取属性并执行其中的一些功能。我已经设法通过获取脚本所在的iframe的mshtml.HTMLDocument并使用以下代码来获取javascript对象:

Dim jsObject as Object
jsObject = htmldoc.Script.jsObject

jsObject作为{System .__ ComObject}存在,我可以用它来执行任何函数或读取它的属性,如下所示:

Dim value as String = jsObject.FunctionThatReturnsAString()
jsObject.FunctionTHatDoesSomethingInWebApp("Param1", "Param2")

这很有效。但是,当我使用jsObject离开页面/框架并返回它时,相同的代码在从框架再次获取javascript对象时抛出异常(即执行以下行):

jsObject = htmldoc.Script.jsObject

例外:未找到成员。 (HRESULT异常:0x80020003(DISP_E_MEMBERNOTFOUND))

如果我停止调试并重新启动,它会再次起作用(直到我离开页面等)。我不确定发生了什么导致javascript对象消失,就我的应用程序而言。我假设这是由于我的应用程序持有对COM对象的引用,我需要以某种方式释放它(特别是因为它有一个基本类型的MarshalByRefObject - 这是有意义的,因为它是在应用程序域之间传递)。

为什么会这样?有没有更好的方法来访问javascript对象,它的属性和功能?

1 个答案:

答案 0 :(得分:1)

在我的例子中,我发现了实现我需要的更好方法。我不是直接作为COM对象访问jsObject(并担心Marshaling等),而是使用:

  • execScript调用没有返回值的函数或
  • 在我正在使用的框架中创建一个隐藏的div元素,将该div的innerHTML设置为等于我使用execScript感兴趣的任何javascript变量/函数返回值,然后从DOM中单独读取该值< / LI>

要读取变量/函数返回,请使用以下vb.net函数:

Private Function getJScriptVariable(ByVal JScript As String)
    Dim command As New StringBuilder()
    command.Append("var e = document.getElementById('Matt_JScriptReturn');")
    command.Append("if (e == null) {")
    command.Append("var e = document.createElement('div');")
    command.Append("e.id = 'Matt_JScriptReturn';")
    command.Append("e.type = 'hidden';")
    command.Append("document.body.appendChild(e);")
    command.Append("}")
    command.Append("e.innerHTML = ")
    command.Append(JScript)
    command.Append(";")

    'fMaster is the frame containing the javascript's mshtml.IHTMLWindow2
    fMaster.execScript(command.ToString(), "JScript")

    'N.B. fMaster_Document is the fMaster's mshtml.HTMLDocument
    Return fMaster_Document.getElementById("Matt_JScriptReturn").innerHTML

    'Optionally execScript to remove element from DOM at this point
End Function

然后我将使用该函数如下(尊重我在原始问题中的例子):

Dim value as String = getJScriptVariable("jsObject.FunctionThatReturnsAString()")

要执行javascript代码而不需要返回值,我只需按如下方式执行:

fMaster.execScript("jsObject.FunctionTHatDoesSomethingInWebApp('Param1', 'Param2')")

我仍然很有兴趣找到为什么我之前遇到问题,javascipt对象在离开页面并返回后无法访问,但这解决了我的问题所以我现在很高兴!我希望这在某些方面可以帮助别人。