在Internet Explorer实例中运行JavaScript函数

7
我正在使用的是 <\p>
SHDocVw.InternetExplorer ie = new SHDocVw.InternetExplorer()

控制/自动化Internet Explorer的一个实例。在某些页面上,我想运行一个JavaScript函数(init())。似乎最好的方法是使用HtmlDocumentInvokeScript方法,我一直在尝试以下操作,但没有成功:

void ie_DocumentComplete(object pDisp, ref object URL)
{
  System.Windows.Forms.HtmlDocument doc = ie.Document;
  doc.InvokeScript("init");
}

这段代码失败是因为doc为空。我似乎无法从ie.Document中获取System.Windows.Forms.HtmlDocument。除了尝试上述方法外,我还尝试了以下方法:

System.Windows.Forms.HtmlDocument doc2 = (System.Windows.Forms.HtmlDocument)ie.Document;

并且

System.Windows.Forms.HtmlDocument doc2 = ie.Document as System.Windows.Forms.HtmlDocument;

有没有什么想法可以让这个工作-或者更好的方式在页面上运行脚本?

谢谢!

编辑

运行JavaScript函数的另一种方法似乎是:

SHDocVw.InternetExplorer ie = new SHDocVw.InternetExplorer()
mshtml.HTMLDocument doc = ie.Document;
mshtml.IHTMLWindow2 win = doc.parentWindow as mshtml.IHTMLWindow2;
win.execScript("init();", "javascript");

但是这条线路

mshtml.IHTMLWindow2 win = doc.parentWindow as mshtml.IHTMLWindow2;

抛出一个错误,说它是一个无效的转换(InvalidCastException) - 即使 IntelliSense(和 MSDN) 说 doc.parentWindow 是一个 IHTMLWindow2。有什么想法吗?(我已经确保在运行该代码之前页面已经完全加载)

5个回答

8

这个问题与线程有关 - 我浪费了很多时间来解决STA问题,你可能会认为我现在应该学会了:).

无论如何,我找到了一种方法来使我发布的第二段代码工作,并在IE窗口中运行JavaScript函数!以下是代码:

this.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() =>
                {

                        mshtml.HTMLDocument doc = ie.Document;

                        mshtml.IHTMLWindow2 win = doc.parentWindow as IHTMLWindow2;
                        win.execScript("init();", "javascript");


                }));

希望这能帮助到某些人!

如果您能具体说明解决线程问题所采取的措施,那么您的回答更有可能帮到别人。 :-) - EricLaw
顺便提一下:我在一些页面上看到,Dispatcher.Invoke是来自WPF的。你有没有普通C#项目的解决方案? - miny1997

5

在单线程单元(STA)中,您需要访问document.parentWindow。可以尝试以下方法:

  private WebBrowser _webBrowser; //initialize this somewhere

  private void ExecuteJavaScript()
  {
     Thread aThread = new Thread(ExecuteJavaScriptWorker);
     aThread.SetApartmentState(ApartmentState.STA);
     aThread.Start(); 
  }

  private void ExecuteJavaScriptWorker()
  {
      HTMLDocument _document = _webBrowser.Document;
      _document.parentWindow.execScript("alert('Arbitrary javascript code')", "javascript");
  }

3
您可以简单地执行以下操作:
ie.Navigate("javascript:" + jsScript);

其中ie是InternetExplorer的实例。


1
非常有限!就你可以执行的代码而言! - user2640130

1
这是一个获取某个页面文档的示例。它与上面显示的示例非常接近,但有一个小但重要的区别 - 我使用了Navigate2方法 - 这个方法可以正常工作。
public static mshtml.HTMLDocument NavigateTo(String anUrl) {
  object locEmpty = 0;
  object locUrl = anUrl;
  SHDocVw.InternetExplorer _ie = new SHDocVw.InternetExplorer();
  _ie.Visible = true;
  _ie.Navigate2(locUrl, ref locEmpty, ref locEmpty, ref locEmpty, ref locEmpty);
  return(_ie.Document);
}   

这个例子适用于在IE中打开的所有常规窗口(非模态窗口)。对于模态窗口(或模态对话框),此示例不起作用。

0

SHDocVw.InternetExplorer.Document是mshtmlHTMLDocumentClass类型,所以您需要引用Microsoft.mshtml。

mshtml.HTMLDocumentClass doc = (mshtml.HTMLDocumentClass)ie.Document;

ie对象还必须导航到某个地方,文档才有值。例如

object test = new object();
ie.Navigate("c:\\tmp\\test1.html", ref test, ref test, ref test, ref test);

总体初始化:

SHDocVw.InternetExplorer ie = new SHDocVw.InternetExplorer();
object test = new object();
ie.Navigate("c:\\tmp\\test1.html", ref test, ref test, ref test, ref test);
mshtml.HTMLDocumentClass doc = (mshtml.HTMLDocumentClass)ie.Document;

谢谢您的回答,但我在尝试使用那行代码时遇到了问题。它给出了以下编译器错误:"Interop 类型 'mshtml.HTMLDocumentClass' 无法嵌入。请改用相应的接口。" 有什么想法吗? - Evan
mshtml.HTMLDocumentClass doc = (mshtml.HTMLDocumentClass)ie.Document; mshtml.HTMLDocumentClass doc = (mshtml.HTMLDocumentClass)ie.Document; - Evan
你是否在引用中添加了 Microsoft.mshtml 的参考?(不是 Interop)它在 .net 引用列表中。 - Jack B Nimble
是的,我有参考资料。我已经能够控制资源管理器窗口并打开新页面,只是无法运行脚本。不过我正在使用C# 4.0,这可能与此有关吗?我之所以问是因为它会改变一些COM方面的东西(例如可以调用ie.Navigate而不必填写额外的参数)。再次感谢! - Evan
这与C# 4.0有点关系 - 当嵌入mshtml时,您不能使用HTMLDocumentClass。但是,我将嵌入值设置为false,以便可以运行上面的代码,但我无法从HTMLDocumentClass转换为Windows.Forms.HTMLDocument,以便我可以使用InvokeScript()。有什么想法吗? - Evan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接