Answered by:
Exception occurs when IHTMLWindow2 window = theDoc.parentWindow;

Question
-
As title,
I try to execute a javascript with HDocVw.InternetExplorerClass so after the documentComplete event, I first get the reference to IHTMLWindow2 window = theDoc.parentWindow; and then window.execScript("goSearch()", "JavaScript");.
However, IHTMLWindow2 window = theDoc.parentWindow throws a exception:
System.InvalidCastException: Specified cast is not valid.
at System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData)
at mshtml.HTMLDocumentClass.get_parentWindow()I have no idea about the reason of this excpetion. Could any experienced one provide me some guidelines to fix this error?
Thanks a million.
Ricky.
Answers
-
The problem is you can't make calls from outside the thread that created the Document object. In other words, you must make Document calls from within the same thread.
So instead of threadpool, gonna have to fake it with some kind of array of STA threads. Ugh...! -
this is what worked for me:
ManualResetEvent[] aDoneEvents = new ManualResetEvent[_MaxThreads];
for (int i = 0; i < aDoneEvents.Length; i++)
aDoneEvents= new ManualResetEvent(false);
//init aDataForThreadfor (int i = 0; i < _MaxThreads; i++)
{
Thread aThread = new Thread(new ParameterizedThreadStart(ThreadWorker));
aThread.SetApartmentState(ApartmentState.STA);
aThread.IsBackground = true;
aThread.Start(new ThreadData(aDataForThread, aDoneEvents));
} // for
WaitAll(aDoneEvents);
Then inside the ThreadWorker method you initialize your Browser object, make your Document calls, etc...
Bottom line is you can't use ThreadPool and IE because of COMpartmentalization.
All replies
-
I get the same error doing the same thing you're trying to do.
Funny thing is, I have a non-threaded version of the app where my code does not fail, but the threaded version does fail on that code.
Looks like theDoc doen't get fully intialized. If you'll notice, Parent Window and Frames, and some other properties have exceptions.
If anyone has any hints to help out, that would be great!
Thanks! -
The problem is you can't make calls from outside the thread that created the Document object. In other words, you must make Document calls from within the same thread.
So instead of threadpool, gonna have to fake it with some kind of array of STA threads. Ugh...! -
-
this is what worked for me:
ManualResetEvent[] aDoneEvents = new ManualResetEvent[_MaxThreads];
for (int i = 0; i < aDoneEvents.Length; i++)
aDoneEvents= new ManualResetEvent(false);
//init aDataForThreadfor (int i = 0; i < _MaxThreads; i++)
{
Thread aThread = new Thread(new ParameterizedThreadStart(ThreadWorker));
aThread.SetApartmentState(ApartmentState.STA);
aThread.IsBackground = true;
aThread.Start(new ThreadData(aDataForThread, aDoneEvents));
} // for
WaitAll(aDoneEvents);
Then inside the ThreadWorker method you initialize your Browser object, make your Document calls, etc...
Bottom line is you can't use ThreadPool and IE because of COMpartmentalization. -
-
Hi ,
I have a lot a problems b/c of the Multi-Threading anyone have a full solution that works ?
I try : PhrankBooth soloutions, but its doesn't seems to work well for me,
maybe i didn't implment it well .
Thanks
Naty -
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"); }
- Proposed as answer by Mozart Al Khateeb Monday, July 16, 2018 6:29 AM
-