gpt4 book ai didi

c# - WebBrowser Navigate 和 InvokeScript 的流程

转载 作者:太空宇宙 更新时间:2023-11-03 21:43:17 24 4
gpt4 key购买 nike

我无法理解我正在构建的这个函数的流程。

    public void PortalLogin(AutoResetEvent signal)
{
// Navigate to portal
string portalUrl = "website_name";
string portalEmail = "email@email.com";
string portalPassword = "password";
Action action2 = () =>
{
webBrowser2.Tag = signal;
webBrowser2.Navigate(portalUrl);
webBrowser2.DocumentCompleted -= WebBrowserDocumentCompleted;
webBrowser2.DocumentCompleted += WebBrowserDocumentCompleted;
};
webBrowser2.Invoke(action2);
signal.WaitOne();

// Login to O365 portal
webBrowser2.Invoke(new Action(() =>
{
HtmlElement head = webBrowser2.Document.GetElementsByTagName("head")[0];
HtmlElement testScript = webBrowser2.Document.CreateElement("script");
IHTMLScriptElement element = (IHTMLScriptElement)testScript.DomElement;
element.text = "function PortalLogin() { document.getElementById('userid').value = '" + portalEmail + "'; document.getElementById('password').value = '" + portalPassword + "'; document.getElementById('login').submit(); }";
head.AppendChild(testScript);
webBrowser2.Document.InvokeScript("PortalLogin");
}));
}

... more functions after this

当我单步执行它时,它似乎并没有“及时”调用脚本的 document.getElementById('login').submit(); 部分。在 InvokeScript 完全 完成之前,我如何确保什么都不会发生?

此外 - 如果您看到任何多余的代码或可以清理的东西,那也很棒。

编辑:这是 DocumentCompleted 函数。

private void WebBrowserDocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs Url)
{
((AutoResetEvent)((WebBrowser)sender).Tag).Set();
}

最佳答案

几点:

您可以添加 DocumentCompleted一次在外面的事件处理程序 PortalLogin并重用相同的处理程序。您正在使用 AutoResetEventsignal.WaitOne() 之后自动重置为无信号状态, 所以你应该只用一个永久处理程序来处理 DocumentCompleted .

你确定document.getElementById('login')返回 submit 的有效元素方法可用?在调用 InvokeScript 之前验证.您可以分两步进行登录,例如:

            element.text = "function PortalLogin() { document.getElementById('userid').value = '" + portalEmail + "'; document.getElementById('password').value = '" + portalPassword + "';  }" +
"function ExecuteLogin() { document.getElementById('login').submit(); }";
head.AppendChild(testScript);
webBrowser2.Document.InvokeScript("PortalLogin");
// verify document.getElementById('login') here
webBrowser2.Document.InvokeScript("ExecuteLogin");

注意:如果成功,提交最终会触发另一个 DocumentCompleted事件。

我将使用单线程和 await/async pattern 重构此代码. DocumentCompleted可以用 TaskCompletionSource 包装成一个任务(这里是 how )。

下面是使用 async/await 的样子.在有MessageBox.Show的地方你可以做你的 DOM 操作。请注意,这一切都在主 UI 线程上完成(当然是异步的)。对我来说看起来容易多了。

void Form1_Load(object sender, EventArgs e)
{
var task = DoNavigationAsync();
task.ContinueWith((t) =>
{
MessageBox.Show("Navigation done!");
}, TaskScheduler.FromCurrentSynchronizationContext());
}

struct Void {}; // use an empty struct as parameter to generic TaskCompletionSource

async Task DoNavigationAsync()
{
Void v;
TaskCompletionSource<Void> tcs = null;
WebBrowserDocumentCompletedEventHandler documentComplete = null;

documentComplete = new WebBrowserDocumentCompletedEventHandler((s, e) =>
{
// more of DocumentCompleted can possibly be fired due to dynamic navigation inside the web page, we don't want them!
this.WB.DocumentCompleted -= documentComplete;
tcs.SetResult(v); // continue from where awaited
});

// navigate to www.bing.com
tcs = new TaskCompletionSource<Void>();
this.WB.DocumentCompleted += documentComplete;
this.WB.Navigate("http://www.bing.com");
await tcs.Task;
// do whatever you want with this instance of WB.Document
MessageBox.Show(this.WB.Document.Url.ToString());

// navigate to www.google.com
tcs = new TaskCompletionSource<Void>();
this.WB.DocumentCompleted += documentComplete;
this.WB.Navigate("http://www.google.com");
await tcs.Task;
// do whatever you want with this instance of WB.Document
MessageBox.Show(this.WB.Document.Url.ToString());

// navigate to www.yahoo.com
tcs = new TaskCompletionSource<Void>();
this.WB.DocumentCompleted += documentComplete;
this.WB.Navigate("http://www.yahoo.com");
await tcs.Task;
// do whatever you want with this instance of WB.Document
MessageBox.Show(this.WB.Document.Url.ToString());

return;
}

关于c# - WebBrowser Navigate 和 InvokeScript 的流程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18280487/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com