Webbrowser:当托管网页上的链接未触发DocumentCompleted时,对活动进行排序

鉴于此方法适用于Web浏览器中的HTML页面:

bool semaphoreForDocCompletedEvent; private void button12_Click(object sender, EventArgs e) { checkBox1.Checked = false; //unchecked if the NAvigating event is fired and Checked after DocumentCompleted is fired, only to have a visual reference on the Form HtmlDocument doc = Program.wb.Document; HtmlElement ele = doc.GetElementById("menuTable"); foreach (HtmlElement sub in ele.All) { if (sub.GetAttribute("href").Contains("something")) { ele = sub; break; } } //PHASE 1: clicking on a Web link to navigate to a page that contains other buttons and links object obj = ele.DomElement; System.Reflection.MethodInfo mi = obj.GetType().GetMethod("click"); mi.Invoke(obj, new object[0]); //PHASE 2: Waiting for document completed in order to be sure the document is fully loaded semaphoreForDocCompletedEvent = WaitForDocumentCompleted(); if (!semaphoreForDocCompletedEvent) throw new Exception("casino in giro!"); ele = doc.GetElementByI("button1").FirstChild.FirstChild.FirstChild.NextSibling; //PHASE 3: clicking on a Web button to open a form obj = ele.DomElement; mi = obj.GetType().GetMethod("click"); mi.Invoke(obj, new object[0]); //PHASE 4: displaying a modal MEssageBox that annoy the user a lot if (checkBox1.Checked == false) MessageBox.Show("non c'è stato document completed"); checkBox1.Checked = false; //PHASE 5: submitting the form (that does not need any imput to be filled in) ele = doc.GetElementById("planet"); ele = ele.FirstChild.NextSibling.NextSibling; obj = ele.DomElement; mi = obj.GetType().GetMethod("submit"); mi.Invoke(obj, new object[0]); } private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { Program.toBox = Program.wb.Document.Body.InnerHtml.ToString(); if (Program.wb.ReadyState == WebBrowserReadyState.Complete) { checkBox1.Checked = true; IsBusy = false; } } private bool WaitForDocumentCompleted() { while (IsBusy) { Application.DoEvents(); Thread.SpinWait(1000); } return true; } 

我需要理解为什么这个代码在显示消息框时像魅力一样运行,而在注释消息时则不然。 我怀疑在这些问题中可以得到解决:

1)当消息框是程序的一部分而不是程序的时候,代码的流程如何? 我的意思是用户按下的代码按下确定?

2)上面用数字3表示的阶段在页面中触发了一些javascript而没有发出导航事件(因此没有DocumentCompleted),但是在没有点击A标签的情况下可以访问一些隐藏的HTML无法访问。 在实践中,它只是更改标签的InnerHtml,在其中创建一个FORM。

3)我尝试为第4阶段实现了几个解决方案,这里显示了一个消息框,一个ThreadSleep(),一个SpinWait(),甚至一个for循环弄乱了所有东西,但所有这些解决方案似乎都不让Webbrowser继续进行可视化屏幕上的表格。 只有消息框才能将其显示在屏幕上,即使用户按下确定并关闭它也非常快。

4)我需要找到一个不涉及外部(用户)输入的解决方案(例如要关闭的Messagebox),以便等待表单在屏幕上显示完全加载,但没有任何事件可以帮助。

评估案例的更多数据: – 我编写的代码对目标有好处,我试图将其分成3个按钮来手动管理时序,并且工作正常。 – 完成的文档不能用于在代码拆分之间切换,因为有大约300页自动化,每个页面可以有10-15种方法来自动化它们,所以不可能为所有这些方法管理单个事件处理程序,而不会构建一个无休止的切换结构。 如果可能的话,我会尽量避免它。 – 我发现了其他用户的一些有趣问题,如下所示,但我的案例没有解决方案:

WebBrowser.IsBusy或ReadyState(VB .NET)的InvalidCastException

检测AJAX何时在WebBrowser中更改DIV中的HTML

http://www.techtalkz.com/vb-net/374234-vb-net-webbrowser-control-how-capture-javascript-events-statusbar-changed-mouseclick-etc.html

有人可以帮我一把

对不起,这是我的第一个post,希望我已经清楚了。 TKS

我在这里发布了我能够找到这个问题的解决方案:我为HtmlElement类型编写了一个扩展方法,如下所示:

 public static bool WaitForAvailability(this HtmlElement tag, string id, HtmlDocument documentToExtractFrom, long maxCycles) { bool cond = true; long counter = 0; while (cond) { Application.DoEvents(); tag = documentToExtractFrom.GetElementById(id); if (tag != null) cond = false; Thread.SpinWait(50000); counter++; if (counter > maxCycles) return false; } return true; } 

这允许等待所需的标签直到它在页面中真正可用的时刻