質問

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 では、Google Chrome のように、タブごとに 1 つのプロセスであるようです) ...したがって、サーバー通信が完了するまで IE インターフェイスがロックアップされます。

当初、URL が (NavigationComplete2 イベント経由で) 利用可能になったらすぐに処理を開始したいと思っていましたが、ユーザーのページが読み込まれる前にサーバー通信が終了すると、<body> タグが利用可能になるのを待機していると、IE もロックされてしまうことがわかりました。コードが HTML 本文を待機している間、無限ループに陥り、前述のループによりページ自体の更新が妨げられます。

これらすべてを実際のユーザーのページの JavaScript に移動することを考えましたが、そうすることで XSS のセキュリティ問題と格闘するワームの缶を開けているようです。

それで...私の質問は次のようなものです:ユーザーのページ DOM を操作しながら、C# IE BHO でコードを非同期に実行することは可能ですか?何人かの友人に聞いてみましたが、ほとんどの人がその可能性は低いと言っていました。私は C/VB.net/JS/AS から来たので、COM と C# に関してはまだ初心者です。

ありがとう!

-トム

役に立ちましたか?

解決

DOM オブジェクトを作成したスレッドからワーカー スレッドにマーシャリングする必要があります。 ここ は、COM と C# がどのように連携するかを非常に詳しく説明しています。

すべての IE DOM オブジェクトは STA オブジェクトです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top