2009-08-05 12 views
2

これまでは、次の関数を使用して、実行中のInternet Explorerインスタンスに対してIWebBrowser2ポインタを取得しました。私は何PIDを指定したIE8ウィンドウのIWebBrowser2ポインタを見つける方法は?

static SHDocVw::IWebBrowser2Ptr findBrowserByPID(DWORD pid) 
{ 
    SHDocVw::IShellWindowsPtr ptr; 
    ptr.CreateInstance(__uuidof(SHDocVw::ShellWindows)); 
    if (ptr == NULL) { 
     return 0; 
    } 

    // number of shell windows 
    const long nCount = ptr->GetCount(); 

    // iterate over all shell windows 
    for (long i = 0; i < nCount; ++i) { 
     // get interface to item no i 
     _variant_t va(i, VT_I4); 
     IDispatchPtr spDisp = ptr->Item(va); 

     SHDocVw::IWebBrowser2Ptr spBrowser(spDisp); 
     if (spBrowser != NULL) { 
      // if there's a document we know this is an IE object 
      // rather than a Windows Explorer instance 
      HWND browserWindow; 
      try { 
       browserWindow = (HWND)spBrowser->GetHWND(); 
      } catch (const _com_error &e) { 
       // in case ->GetHWND() fails 
       continue; 
      } 

      DWORD browserPID; 
      GetWindowThreadProcessId(browserWindow, &browserPID); 
      if (browserPID == pid) { 
       return spBrowser; 
      } 
     } 
    } 
    return 0; 
} 

CreateProcess経由explorer.exeプロセスを起動してから(私はブラウザをいじることができるように)、それにIWebBrowser2Ptrを取得するために、上記の関数を使用することです。

残念ながらIE8はプロセスを再利用するように見えるため、Internet Explorer 8ではこれ以上機能していないようです。

PROCESS_INFORMATION pi; 
// ... 

if (CreateProcess(..., &pi)) { 
    // Wait a bit to give the browser a change to show its window 
    // ... 

    IWebBrowser2 *pWebBrowser = findBrowserByPID(pi.dwProcessId); 
} 

このコードの最初の実行はうまく動作し、2番目のコードシーケンスは決してpWebBrowserウィンドウを取得しません。

デバッグのビットの後、それが(そしてそれが2番目のブラウザインスタンスを起動した後、より多くのを見つけた)findBrowserByPID機能は、ブラウザのウィンドウをたくさん見つけないことが明らかになったが、それらのどれも、新たに開始したプロセスに属していません。すべてのウィンドウは、開始された最初のIEプロセスに属しているようです。

誰かがIE8インスタンスのIWebBrowser2ポインタを取得する別の方法を知っていますか?または、おそらくIE8でプロセスのこの明らかな '再利用'を無効にする方法はありますか?

+2

LCIEを無効にするにはレジストリキーを使用できますが、これはエンドユーザーにとってはサポートされていない設定です。自分のマシン以外でこれを行う場合は、それは適切ではありません。 今日の「pid-to-IWB2」のアプローチは、必ずしも将来的には機能しないことに注意してください。 IEは、この関数にサポートされているAPIを公開していません。 – EricLaw

+0

@EricLaw:ああ、「LCIE」という言葉を削除していただきありがとうございます。これはgoogleのためのものです! –

答えて

1

自分でIEプロセスを起動する場合は、代わりにCreateProcess--を使用しないで、CoCreateInstanceを使用してください。それは、あなたが自由に使うことができるIWebBrowser2を問い合わせることができるオブジェクトを返します。 1つの複雑さは、ナビゲーションが完全性レベル(Vista +)を超えた場合、ポインタが無効になることです。この問題に対処するには、NewProcessイベントを同期させます。これにより、この状態を検出できます。 http://msdn.microsoft.com/en-us/library/aa752084%28VS.85%29.aspx

+0

これは、CoCreateInstanceが必ずしも新しいプロセスを作成するとは限りません。 Webページへの複数のユーザーログインをシミュレートするために、複数のIEウィンドウを自動化しています。ログインデータやその他の情報の共有を避けるため、CreateProcessを使用して毎回新しいプロセスを明示的に作成する必要がありました。 –

+0

元の質問にあなたが書いたコメントを受け入れることができないので、この回答を受け入れます。 :-)「LCIE」という言葉が鍵でした。私はそれを探して、レジストリキーを使ってこの機能を無効にすることができることを発見しました。私は、これが将来のバージョンではうまくいかないかもしれないことを認めていますが、少なくとも上記のコードが再び動作するようになったので、今は回避策があります。ありがとう! –

+1

LCIEが無効になっているか、-nomergeコマンドラインパラメータを渡さない限り、CreateProcessだけでは役に立ちません。 LCIを無効にしなくても、これで十分でしょう。 :-) – EricLaw

1

は、代替アプローチのカップルがあるかもしれない:

は、ここでいくつかの詳細情報を参照してください

  • Get a reference via a HWND

  • 使用WatiNのようなライブラリあなたが役立つかもしれないものは何でもあなたの本当の終わり目標はIEを自動化しようとしている場合です。

関連する問題