InvalidCastException using WebBrowser.IsBusy or ReadyState (VB.NET)

I played with a method that was proposed as an answer to another of my questions ( Automate login and filling out a form? ) And noticed something curious.

The answer to the above question was to use a series of javascript calls as a URL to fill out a web form and submit it. I try to do this automatically inside a VB.NET program without success.

The original example I received does not work, presumably because you are expecting the same stream as the WebBrowser control:

WebBrowser1.Navigate("http://www.google.com") Do While WebBrowser1.IsBusy OrElse WebBrowser1.ReadyState <> WebBrowserReadyState.Complete Threading.Thread.Sleep(1000) Application.DoEvents() Loop WebBrowser1.Navigate("javascript:function%20f(){document.forms[0]['q'].value='stackoverflow';}f();") Threading.Thread.Sleep(2000) 'wait for javascript to run WebBrowser1.Navigate("javascript:document.forms[0].submit()") Threading.Thread.Sleep(2000) 'wait for javascript to run 

If you do not wait at all, this will not work either. The URL you are originally viewing is aborted. But it is interesting that you also cannot β€œnavigate” to javascript calls.

So, I tried two other methods: using the DocumentCompleted event to wait until you navigate to the socket url until the browser finishes loading the page. Unfortunately, DocumentCompleted does not always fire and does not fire after every javascript url.

The second method I tried was to put the wait in a separate thread:

  Private Delegate Sub SetTextDelegate(ByVal TheText As String) Private Sub delSetText(ByVal TheText As String) WebBrowser1.Navigate(TheText) End Sub Private Sub BrowseTo(ByVal URL As String) If WebBrowser1.InvokeRequired Then Me.BeginInvoke(New SetTextDelegate(AddressOf delSetText), URL) Else WebBrowser1.Navigate(URL) End If End Sub Private Sub TargetURL() BrowseTo("http://www.google.com") End Sub Private Sub TypeSomethingIn() BrowseTo("javascript:function%20f(){document.forms[0]['g'].value='test';}f();") End Sub Private Sub SubmitForm() BrowseTo("javascript:document.forms[0].submit()") End Sub Private Sub Wait() While True If WebBrowser1.ReadyState = WebBrowserReadyState.Complete Then Exit Sub Threading.Thread.Sleep(100) End While End Sub Private Sub AutoBrowse() TargetURL() Wait() TypeSomethingIn() Wait() SubmitForm() End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim t As Threading.Thread t = New Threading.Thread(AddressOf AutoBrowse) t.Start() End Sub 

Curiously, the ReadyState (or IsBusy, for that matter) check in the wait loop sometimes raises an InvalidCastException. Presumably, calls to them are not thread safe? I have no idea. If I put the failed call inside the Try block, the wait loop just won't work. In fact, it even seems that the exception is β€œsaved” in order to ruin everything, because even stepping over the code using the try block, Visual Studio freezes for a good 10-20 seconds (it does the same without the try block).

Any ideas?

+2
source share
2 answers

One of the most interesting problems that I experienced and which for me could not find a solution on the Internet was the problem associated with Managing WebBrowser. The fact is that when I tried to access the document property of the WebBrowser control instance, I got Msgstr "Invalid casting exception". The fact is that the WebBrowser control is designed to work in a single thread. Therefore, to fix this, you should only check InvokeRequired, and if this value is true, then call the logic from the delegate specified in the browser. Invoke Method (...).

A source

+3
source

Following msdn , the article: "There are four control methods that are safe for threads: Invoke, BeginInvoke, EndInvoke and the CreateGraphics and InvokeRequired Property"

Therefore, a call to WebBrowser1.ReadyState in Sub Wait is not thread safe

+1
source

Source: https://habr.com/ru/post/893209/


All Articles