C# で開発中の IE BHO があります。ユーザーが何らかの操作を行うのを待ち、サーバーに接続してデータをダウンロードし、現在読み込まれている Web ページの DOM を結果で変更することになっています。
COM のコンパートメント化とスレッド化のルールに関連する一見克服できない問題に直面しています。つまり、現在のスレッドの外で IE DOMDocument にアクセスできないようで、ロックせずに何かを非同期的に実行する方法が思い浮かびません。終了するまで IE を起動します。
私の最初の試みでは、バックグラウンドのサーバー通信がイベント駆動型の方法で行われました。私のプログラムは、mshtml イベント (BeforeNaviagate2 または DocumentComplete など) 内から通信を開始し、別のイベント ハンドラー内から結果をポストしました。サーバー通信オブジェクトが作業を終了したときに起動されます。
この手法は、私がまとめた簡単なシミュレーター (WebBrowser コントロールを備えた単純なアプリ) ではうまく機能しましたが、IE では別のスレッドを介してページ DOM を変更しようとしたため、COM 例外がスローされました。
そこで、すべてを同じ関数に保持し、次のように、サーバー通信オブジェクトが while ループで作業を行うのをコードで待機させようとしました。
int waited = 0;
while (!OurServerCommRequest.ready) {
System.Threading.Thread.Sleep(1);
Application.DoEvents();
waited++;
if (waited > constants.TIMEOUT_OURSERVER_REQUEST) {
log.wL("Timed out");
}
}
このアプローチの問題は、コードが元のスレッドにとどまっている間、コードが起動された IE プロセスと同期して実行されることです (IE8 では、タブごとに 1 つのプロセスであり、Google Chrome のように見えます) ... したがって、ロックアップします。サーバーとの通信が完了するまで IE インターフェースを使用しないでください。
最初は、URL が (NavigationComplete2 イベントを介して) 利用可能になったらすぐに処理を開始したかったのですが、ユーザーのページが読み込まれる前にサーバー通信が終了した場合に <body> タグが利用可能になるのを待つと、IE もロックされることがわかりました。私のコードがHTML本文を待っている間、それは無限ループに入りますが、ページは前述のループに対してそれ自体を更新できません。
これらすべてを実際のユーザーのページの JavaScript に移動することを考えましたが、そうすることで、XSS のセキュリティ問題と格闘する際にワームの缶を開けているようです。
だから...私の質問は次のとおりです.ユーザーのページDOMを操作しながら、C# IE BHOで非同期にコードを実行することは可能ですか? 私は何人かの友人に尋ねましたが、ほとんどの人はそうではないと言いました. C/VB.net/JS/AS 出身で、COM と C# についてはまだ初心者です。
ありがとうございました!
-トム