Reputation: 4550
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
Reputation: 180
you can simple do:
ie.Navigate("javascript:" + jsScript);
where ie is your instance of internetexplorer
Upvotes: 3
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
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
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
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