Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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)

like image 542
Evan Avatar asked Aug 18 '10 17:08

Evan


4 Answers

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!

like image 64
Evan Avatar answered Oct 13 '22 01:10

Evan


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");
  }
like image 40
Jacob Tabak Avatar answered Oct 13 '22 01:10

Jacob Tabak


you can simple do:

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

where ie is your instance of internetexplorer

like image 30
Fernando Reis Guimaraes Avatar answered Oct 13 '22 00:10

Fernando Reis Guimaraes


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.

like image 45
Alex Avatar answered Oct 13 '22 00:10

Alex