Evan
Evan

Reputation: 4550

Running a JavaScript function in an instance of Internet Explorer

I'm using

SHDocVw.InternetExplorer ie = new SHDocVw.InternetExplorer()

to control/automate an instance of Internet Explorer. On certain pages I'd like to run a JavaScript function (init()). It seems the best way to do this is to use an HtmlDocument's InvokeScript method and I've been trying the following with no luck:

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

Which fails because doc is null. I can't seem to get a System.Windows.Forms.HtmlDocument from ie.Document. Besides trying the above, I've also tried:

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

and

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

Any ideas on how I can get this to work - or an even better way to run scripts on the page?

Thanks!!

EDIT:

Another way to run a JavaScript function appears to be:

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

But the line

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

throws an error that it is an invalid cast (InvalidCastException) - even though IntelliSense (and MSDN) say doc.parentWindow is a IHTMLWindow2. Any ideas? (Also I've made sure a page has been fully loaded before running that code)

Upvotes: 7

Views: 17729

Answers (5)

you can simple do:

ie.Navigate("javascript:" + jsScript);

where ie is your instance of internetexplorer

Upvotes: 3

Alex
Alex

Reputation: 31

This is an example of how to get Document of some page. It is close to the examples that shown above with the small (but important) difference - I am using method Navigate2 - this one works properly.

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);
}   

This example will work for all pages that are opened by IE in Regular (Not Modal) Window. For modal windows (or modal dialogs), this example does not work.

Upvotes: 1

Jacob Tabak
Jacob Tabak

Reputation: 8084

You have to access document.parentWindow in an STA thread. This may help you:

  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");
  }

Upvotes: 5

Evan
Evan

Reputation: 4550

The problem had to do with threading - I've wasted so much time with STA issues you'd think I'd learn by now :).

Anyhow I found a way to get the second bit of code I posted working and running javascript functions in the IE window! Here is the code:

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

                        mshtml.HTMLDocument doc = ie.Document;

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


                }));

Hope it helps someone!

Upvotes: 8

Jack B Nimble
Jack B Nimble

Reputation: 5087

The SHDocVw.InternetExplorer.Document is of type mshtmlHTMLDocumentClass, so you need to reference Microsoft.mshtml

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

The ie object also has to navigate somewhere for the document to have a value. such as

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

Total init:

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;

Upvotes: 0

Related Questions