Running a JavaScript function in an instance of Internet Explorer

17,185

Solution 1

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!

Solution 2

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

Solution 3

you can simple do:

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

where ie is your instance of internetexplorer

Solution 4

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.

Share:
17,185

Related videos on Youtube

Evan
Author by

Evan

Updated on June 04, 2022

Comments

  • Evan
    Evan almost 2 years

    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)

  • EricLaw
    EricLaw over 13 years
    Your answer would be more likely to help if you explained specifically what you did to solve the threading issue. :-)
  • Karmen Sali
    Karmen Sali about 8 years
    Very limited! in terms of what code you can execute!
  • miny1997
    miny1997 almost 6 years
    BTW: As I have seen on some pages, Dispatcher.Invoke is from WPF. Do you have a solution for normal C# projects.