Золотое правило WinForms: НИКОГДА, НИКОГДА не используйте Application.DoEvents()
, чтобы пользовательский интерфейс оставался отзывчивым! Если вам нужно его использовать, вы почти всегда делаете что-то не так (см.: Поддержание адаптивности пользовательского интерфейса и опасности Application.DoEvents) .
Тяжелые операции никогда не должны выполняться в потоке пользовательского интерфейса, а должны выполняться в фоновом потоке. Существует несколько способов выполнения работы пользовательского интерфейса, например Задачи, потоки или с помощью BackgroundWorker
.
ОДНАКО в этом случае вам даже не нужен цикл. WebBrowser
имеет DocumentCompleted
событие, которое вызывается каждый раз, когда страница (или iframe
внутри страницы) полностью загружается. Используйте это, чтобы знать, когда выполнять ваш код.
С учетом сказанного, вот как вы можете перенести его на DocumentCompleted
:
WebBrowserWindow.WebBrowser1.Document.Window.Frames(2).Document.GetElementById("username").SetAttribute("value", sUser)
WebBrowserWindow.WebBrowser1.Document.Window.Frames(2).Document.GetElementById("password").SetAttribute("value", sPass)
Dim DocumentCompletedHandler As WebBrowserDocumentCompletedEventHandler = _
Sub(dcsender As Object, dcargs As WebBrowserDocumentCompletedEventArgs)
If WebBrowserWindow.WebBrowser1.ReadyState = WebBrowserReadyState.Complete Then
RemoveHandler WebBrowserWindow.WebBrowser1.DocumentCompleted, DocumentCompletedHandler
'Put the code that should be executed when the user has logged in here.
End If
End Sub
AddHandler WebBrowserWindow.WebBrowser1.DocumentCompleted, DocumentCompletedHandler
'Any code put here won't wait for the user to log in, it wil be executed pretty much immediately.
Вот небольшой тестовый проект: http://www.mydoomsite.com/sourcecodes/WebBrowser_WaitForUserInteraction.zip< /а>
В конечном счете, весь ваш код можно изменить на:
WebBrowserWindow.WebBrowser1.Navigate("[...]")
Dim FirstDocumentCompletedHandler As WebBrowserDocumentCompletedEventHandler = _
Sub()
'Check if:
' - The web browser has finished loading.
' - WebBrowser1.Document is not Null.
' - WebBrowser1.Document.Body is not Null.
' - WebBrowser1.Document.Body.InnerHtml is not Null.
' - WebBrowser1.Document.Body.InnerHtml contains "Login".
If WebBrowserWindow.WebBrowser1.ReadyState = WebBrowserReadyState.Complete AndAlso _
WebBrowserWindow.WebBrowser1.Document IsNot Nothing AndAlso _
WebBrowserWindow.WebBrowser1.Document.Body IsNot Nothing AndAlso _
WebBrowserWindow.WebBrowser1.Document.Body.InnerHtml IsNot Nothing AndAlso _
WebBrowserWindow.WebBrowser1.Document.Body.InnerHtml.Contains("Login") Then
'The code put in here will execute when the page loads the first time, and the above conditions are met.
'We are at the login page. Enter the credentials.
WebBrowserWindow.WebBrowser1.Document.Window.Frames(2).Document.GetElementById("username").SetAttribute("value", sUser)
WebBrowserWindow.WebBrowser1.Document.Window.Frames(2).Document.GetElementById("password").SetAttribute("value", sPass)
Dim SecondDocumentCompletedHandler As WebBrowserDocumentCompletedEventHandler = _
Sub(dcsender As Object, dcargs As WebBrowserDocumentCompletedEventArgs)
If WebBrowserWindow.WebBrowser1.ReadyState = WebBrowserReadyState.Complete Then
RemoveHandler WebBrowserWindow.WebBrowser1.DocumentCompleted, SecondDocumentCompletedHandler
'The code put in here will be executed after the user has pressed "Login".
MsgBox("it works")
WebBrowserWindow.Close()
Me.Close()
End If
End Sub
AddHandler WebBrowserWindow.WebBrowser1.DocumentCompleted, SecondDocumentCompletedHandler 'Add the second DocumentCompleted event handler.
RemoveHandler WebBrowserWindow.WebBrowser1.DocumentCompleted, FirstDocumentCompletedHandler 'Remove the first DocumentCompleted event handler.
End If
End Sub
AddHandler WebBrowserWindow.WebBrowser1.DocumentCompleted, FirstDocumentCompletedHandler
'Again, any code put here will execute almost immediately, thus NOT waiting for the page to load.
Альтернативно
... если вы считаете, что лямбды везде слишком беспорядочны, вы можете вернуться к использованию обычных методов:
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
WebBrowserWindow.WebBrowser1.Navigate("[...]")
AddHandler WebBrowserWindow.WebBrowser1.DocumentCompleted, AddressOf WebBrowserWindow_FirstDocumentCompleted
End Sub
Private Sub WebBrowserWindow_FirstDocumentCompleted(sender As System.Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs)
'Check if:
' - The web browser has finished loading.
' - WebBrowser1.Document is not Null.
' - WebBrowser1.Document.Body is not Null.
' - WebBrowser1.Document.Body.InnerHtml is not Null.
' - WebBrowser1.Document.Body.InnerHtml contains "Login".
If WebBrowserWindow.WebBrowser1.ReadyState = WebBrowserReadyState.Complete AndAlso _
WebBrowserWindow.WebBrowser1.Document IsNot Nothing AndAlso _
WebBrowserWindow.WebBrowser1.Document.Body IsNot Nothing AndAlso _
WebBrowserWindow.WebBrowser1.Document.Body.InnerHtml IsNot Nothing AndAlso _
WebBrowserWindow.WebBrowser1.Document.Body.InnerHtml.Contains("Login") Then
'We are at the login page. Enter the credentials.
WebBrowserWindow.WebBrowser1.Document.Window.Frames(2).Document.GetElementById("username").SetAttribute("value", sUser)
WebBrowserWindow.WebBrowser1.Document.Window.Frames(2).Document.GetElementById("password").SetAttribute("value", sPass)
AddHandler WebBrowserWindow.WebBrowser1.DocumentCompleted, AddressOf WebBrowserWindow_SecondDocumentCompleted 'Add the second DocumentCompleted event handler.
RemoveHandler WebBrowserWindow.WebBrowser1.DocumentCompleted, AddressOf WebBrowserWindow_FirstDocumentCompleted 'Remove the first DocumentCompleted event handler.
End If
End Sub
Private Sub WebBrowserWindow_SecondDocumentCompleted(sender As System.Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs)
If WebBrowserWindow.WebBrowser1.ReadyState = WebBrowserReadyState.Complete Then
RemoveHandler WebBrowserWindow.WebBrowser1.DocumentCompleted, AddressOf WebBrowserWindow_SecondDocumentCompleted
'Put the code that should be executed when the user has logged in here.
MsgBox("it works")
WebBrowserWindow.Close()
Me.Close()
End If
End Sub
person
Visual Vincent
schedule
21.02.2017