InvalidCastException с WebBrowser.IsBusy или ReadyState (VB .NET)

Я играл с методом, который был предложен в качестве ответа на другой из моих вопросов (Автоматизировать вход на сайт и заполнение форм?) и заметил что-то любопытное.

Ответ на поставленный выше вопрос состоял в том, чтобы использовать серию вызовов javascript в качестве URL-адресов, чтобы заполнить веб-форму и отправить ее. Я пытался сделать это автоматически в программе VB .NET безуспешно.

Исходный пример, который я привел, не работает, вероятно, потому, что вы ожидаете в том же потоке, в котором работает элемент управления WebBrowser:

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

Если вы вообще не ждете, это тоже не сработает. URL-адрес, по которому вы первоначально просматриваете, прерван. Но, что интересно, вы не можете выполнить «навигацию» к вызовам javascript без задержки.

Итак, я попробовал два других метода: использование события DocumentCompleted для ожидания перехода к URL-адресу гнезда, пока браузер не завершит загрузку страницы. К сожалению, DocumentCompleted не всегда срабатывает и, похоже, не срабатывает после каждого URL-адреса JavaScript.

Второй метод, который я попробовал, состоял в том, чтобы поместить ожидание в отдельный поток:

 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

Любопытно, что проверка ReadyState (или IsBusy, в этом отношении) в цикле ожидания иногда вызывает InvalidCastException. Предположительно, звонки на них не безопасны? Понятия не имею. Если я помещаю вызывающий вызов вызов в блок Try, цикл ожидания просто не работает. На самом деле, даже кажется, что исключение «сохраняется», чтобы все испортить, потому что даже при пошаговом выполнении кода с блоком try Visual Studio зависает на добрые 10–20 секунд (то же самое происходит и без блока try).

Есть идеи?

Ответы на вопрос(2)

Ваш ответ на вопрос