2011-06-12 19 views
12

WebページでいくつかのJSスクリプトを呼び出すために使用したいと思っています。私はこれを持っている:コンソールアプリケーションでWebブラウザーを使用する

static void Stuff() 
    { 
     WebBrowser browser = new WebBrowser(); 
     browser.Navigate("http://www.iana.org/domains/example/"); 
     HtmlDocument doc = browser.Document; 
     //doc.InvokeScript("someScript"); 
     Console.WriteLine(doc.ToString()); 
    } 

    static void Main(string[] args) 
    { 
     Console.WriteLine("hi"); 
     var t = new Thread(Stuff); 
     t.SetApartmentState(ApartmentState.STA); 
     t.Start(); 
    } 

質問1:私はdoc.ToString()を取得しようとすると例外「を設定していないオブジェクト参照」を取得します。どうして?

質問2:HTMLドキュメントからメインプログラムにデータを取得するにはどうすればよいですか? WebBrowserには別のスレッドが必要です。これには値を返すことのできない静的メソッドが必要です。 docMain()に戻すには、どうすればいいですか?

+0

スタティックメソッドは実際に値を返すことができます。それはできないスレッドです。また、スレッド*は非静的メソッドを使用できます。 – icktoofay

+0

なぜこれがダウン表示されていますか? – Amy

答えて

10

正しいアイデア、間違った実行。 WebBrowser.Navigate()は、Webブラウザに開始を要求しただけです。それには典型的に数百ミリ秒かかる。 Internet Explorerは内部的にスレッドを開始してジョブを終了します。これは、DocumentCompletedイベントを発生させることによっていつ完了するかを示します。あなたはそれを待たずに、まずクラッシュシティです。

次の問題は、コードでDocumentCompletedイベントが発生しないことです。 STA契約を尊重する必要があります。メッセージループをポンピングする必要があります。 Webページを取得するためにIEが使用するようなバックグラウンドスレッドが、ジョブが完了したスレッドにというスレッドを伝えるのは、全能です。

必要な定型文コードはthis answerです。

+0

連鎖活動についてどう思いますか?いくつかのページに移動し、テキストボックスにテキストを入力して検索をクリックするか、移動します。 WebBrowserオブジェクトをグローバルにし、4つのメソッドを連動させ、ナビゲートし、ドキュメントを完了し、テキストを入力し、goを押し、entertextandhitgoのドキュメント完了イベントをチェーンする必要がありますか? – NathanTempelman

+1

ステートマシンは、非同期プログラミングの問題に対する単純なソリューションです。整数または列挙型で状態を追跡するだけです。 –

+1

ちょっとした注意:ユーザーの操作がなくてもWebBrowserコントロールを自動化しようとすると、 'webBrowser.ScriptErrorsSuppressed = true' *を設定しないかぎり、ポップアップダイアログで深刻な問題に遭遇します。(その名前にもかかわらず、 、スクリプトエラーだけでなく)*。 [参照](http://stackoverflow.com/a/20612526/238419)。 –

関連する問題