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?