1

だから私はいくつかのウェブAPIのためにいくつかの自動テストを行っています。System.Windows.Forms.WebBrowserクラスを使用して、すべてコンソールからページに移動し、テキストを入力して、ボタンを押すことができるかどうかを確認しようとしています。検索バーにテキストを入力して検索を押すことは、私がやろうとしていることとほとんど同じであるため、テストにウィキペディアを使用することにしました。

最初に、この質問のコードを使用しました。

私が抱えている問題は、2つのアクションをつなぎ合わせることができないように見えることです。1)ウィキペディアに移動します。2)検索ボックスにテキストを入力して[移動]をクリックします。ウィキペディアに移動します。ステートマシンを使ってみるように言われましたが、それがどのように見えるのかよくわかりません。現状では、2回目にrunBrowserメソッドに戻ると、行br.Document.GetElementByID( "searchInput")はInvalidCastExceptionをスローします。だから私はそこで何が起こっているのか最も霧深いわけではありません。古いスレッドの実行中に新しいスレッドを作成することと関係があると思いますが、古いスレッドを強制終了すると、WebBrowserも強制終了され、「DisconnectedContext」というエラーがスローされます。

これが私のコードです:

static WebBrowser br = new WebBrowser();

static void runBrowserThread()
{

        var th = new Thread(() =>
        {

            br.DocumentCompleted += browser_DocumentCompleted;
            if (state == 0)
            {
                br.Navigate(new Uri("http://en.wikipedia.org/wiki/Main_Page"));
                state++;
            }
            else if (state == 1)
            {

                if (br.Document.GetElementById("searchInput") != null)
                {
                    HtmlElement search = br.Document.GetElementById("searchInput");
                    search.SetAttribute("value", searchterm);
                    foreach (HtmlElement ele in search.Parent.Children)
                    {
                        if (ele.TagName.ToLower() == "input" && ele.Name.ToLower() == "go")
                        {
                            ele.InvokeMember("click");
                            break;
                        }
                    }
                }
                else
                    Console.WriteLine("Meep");
                state++;
            }

            Application.Run();
        });
        th.SetApartmentState(ApartmentState.STA);
        th.Start();       
}

static void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    // var br = sender as WebBrowser;
    if (br.Url == e.Url)
    {
        Console.WriteLine("Natigated to {0}", e.Url);

    }
    HtmlElement search = br.Document.GetElementById("searchInput");
    Console.WriteLine(search.InnerHtml);
    Console.ReadLine();
    // Application.ExitThread();   // Stops the thread
    runBrowserThread();
    return;
}

スレッドをうまく機能させるためにこのコードをどのように配置するかについてのアイデアは本当にありがたいです。

4

1 に答える 1

2

いいえ、あなたはこれを根本的に間違っています。あなたが新しいスレッドを始めたのでそれは爆撃します、決してそれをしないでください。代わりに、DocumentCompletedイベントで状態を確認する必要があります。だから、大まかに:

    var th = new Thread(() =>
    {
        state = 0;
        br.Navigate(new Uri("http://en.wikipedia.org/wiki/Main_Page"));
        Application.Run();
    }

void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    var br = sender as WebBrowser;
    if (state == 0) {
       // You are now on the main page, set the searchInput and submit click
       //...
       state = 1;
    }
    else if (state == 1) {
       // You are now on the searched page, do whatever you need to do
       //...
       // And if you are done:
       Application.ExitThread();
    }
}

さらにページにアクセスする場合は、状態を追加してください。

于 2013-03-22T00:17:28.713 に答える