2011-02-09 16 views
4

実行中のIE8プロセスからSHDocVw.InternetExplorerインスタンスを取得する必要があるプログラムがあります。インスタンスを取得するには、以下のサンプルコードが実行されます。何らかの理由で、Thread.Sleepなしでは動作しません。私は、SHDocVw.ShellWindowsでThread.Sleepを使用するwan'tを使用していません。

Thread.Sleepが削除された場合、Browser.HWNDはm_IEFoundBrowsers内のすべてのインスタンスに対してInvalidCastExceptionをスローします。 Thread.Sleepを使用すると、IE8のウィンドウで動作します。

誰かがThread.Sleepを使用しないでこれを行う方法を知っていますか?

を(私は...通常、それだけで将来的に問題をプッシュし、スリープ機能を使用するために好きではない)のコード例:

InternetExplorer m_IEBrowser = null; 
ShellWindows m_IEFoundBrowsers = new ShellWindowsClass(); 
Thread.Sleep(10);       
foreach (InternetExplorer Browser in m_IEFoundBrowsers) 
{ 
    try 
    { 
     if (Browser.HWND == (int)m_Proc.MainWindowHandle) 
     { 
       m_IEBrowser = Browser; 
       break; 
     } 
     } 
     catch(InvalidCastException ice) 
     { 
      //Do nothing. Browser.HWND could not execute for this item. 
     } 
}   
+0

この前に何が起こりますか? IEを自分で起動していますか?それは始める時間が必要です。 –

+0

'新しいShellWindowsClass()は、使用できる状態になるまでブロックされると思います。 –

+0

私は自分自身にIEを張っていて、始めるには十分な時間があります。私は明日もう一度試してみるが、 "新しいShellWindowsClass()"の後に睡眠が来なければならないようだ。私はVSデバッガの効果はあまり良くありませんが、そこでコードを実行し、ブレークポイントで待っているときに、私がThread.Sleepを持っていなければ同じ問題が発生します。デバッガが何か他のものを導入しているかもしれませんが、今では何らかの理由でスレッドをスリープさせることは、新しいShellWindowsClass()を終了させる唯一の方法です。 –

答えて

5

私はバックアップしているようだ次のリンクに出くわしましたハンスさんのコメント:http://weblogs.asp.net/joberg/archive/2005/05/03/405283.aspx

記事状態:

インターネットは図書館が Bである 「ShellWindowsClass」が含まコントロールすべての シェルウィンドウ(例:IE)の集まりは、デスクトップ上に を生み出しています。そのコンポーネント は、 と呼ばれるイベントハンドラ「Windows Registered」を提供しており、 に接続します。プロセスに が起動したら、 対応するウィンドウが登録されるまで待ちます。 次に、 Internet Explorerコントロールをシェルに接続します。 ウィンドウが見つかりました。 ウィンドウが見つかったかどうかを判断するには、登録済みのウィンドウを まで繰り返して、 ハンドルを見つけようとしました。これは以前に起動したプロセスのハンドル と一致します。 "ManualResetEvent" 同期プリミティブを使用して、ウィンドウ が登録されるまでにある程度の時間を 待機させます。

これらのアイデアを問題に比較的簡単にマップできると思います。

+0

David - 明日見つけた記事で何かしようとします。それは有望に見えます。私は結果を投稿します。 –

+0

@user幸運を祈る! –

+0

この記事ではこのトリックを行いました。ありがとう!私は、回答欄に必要な記事ではない変更を表示します。 –

2

Davidによって投稿された記事は、この問題を解決しました。私のプログラムでコードが実行されるのは、この記事で説明されているように動作します。しかし、私がプログラムを終了すると、開かれたIE8を開いたままにして、プログラムを再び開き、windows_WindowRegisteredメソッドにInvalidCastExceptionsの問題が発生しました。以下のようにこれらの例外を処理することで、必要に応じて機能するようになりました。

のコード例:

private void windows_WindowRegistered(int lCookie) 
{ 
    if (process == null) 
     return; // This wasn't our window for sure 

    for (int i = 0; i < windows.Count; i++) 
    { 
     try 
     { 
      InternetExplorerLibrary.InternetExplorer ShellWindow = windows.Item(i) as InternetExplorerLibrary.InternetExplorer; 
      if (ShellWindow != null) 
      { 
       IntPtr tmpHWND = (IntPtr)ShellWindow.HWND; 
       if (tmpHWND == process.MainWindowHandle) 
       { 
        IE = ShellWindow; 
        waitForRegister.Set(); // Signal the constructor that it is safe to go on now. 

        return; 

       } 
      } 
     } 
     catch (InvalidCastException ice) 
     { 
      //Do nothing. Browser.HWND could not execute for this item. 
     } 
    } 
} 
+0

+1他の読者のためにフォローアップしていただきありがとうございます。そしてあなたは今、upvoteに十分な評判を持っています! –

関連する問題