2

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)メッセージボックスがプログラムの一部である場合とそうでない場合のコードの流れはどうですか?ユーザーがOKを押すまでコードがブロックされているということですか?

2) 上記の番号 3 で示したフェーズでは、Navigating イベントを発行しない (したがって DocumentCompleted を発行しない) ページで JavaScript を起動しますが、A タグをクリックしないとアクセスできない非表示の HTML にアクセスできます。実際には、タグの InnerHtml を変更して、その中に FORM を作成するだけです。

3) フェーズ 4 のいくつかの解決策、ここに示されているメッセージ ボックス、ThreadSleep()、SpinWait()、さらにはすべてを台無しにする for ループを実装しようとしましたが、これらの解決策はすべて、Web ブラウザーが処理を続行できないようです。画面上のフォームを視覚化します。ユーザーが [OK] を押して閉じるのが非常に速い場合でも、メッセージ ボックスだけが画面に表示されます。

4)フォームが画面に完全にロードされて表示されるのを待つために、外部(ユーザー)入力(メッセージボックスを閉じるなど)を必要としないソリューションを見つける必要がありますが、イベントは役に立ちません。

ケースを評価するためのいくつかのデータ: - 私が書いたコードは目的に適しています。手動でタイミングを管理するためにコードを 3 つのボタンに分割しようとしましたが、正常に動作しました。- 自動化された約 300 ページがあり、各ページにはそれらを自動化するための 10 ~ 15 のメソッドを含めることができるため、完成したドキュメントをコード分割の切り替えに使用することはできません。構造体を切り替えます。できれば避けたいと思います。- 次のような他のユーザーの興味深い問題をいくつか見つけましたが、私の場合の解決策はありません:

WebBrowser.IsBusy または ReadyState での InvalidCastException (VB .NET)

AJAX が WebBrowser の DIV で HTML を変更したことを検出する

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

誰か手を貸してくれませんか。

申し訳ありませんが、それは私の最初のスレッドです。Tks

4

1 に答える 1

0

この問題に対して見つけた解決策をここに投稿します。次のように、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;
 }

これにより、必要なタグがページで実際に使用可能になるまで待機することができます。

于 2012-07-06T19:17:50.420 に答える