Domanda

finora, ho usato con successo la seguente funzione per recuperare il puntatore IWebBrowser2 su un'istanza di Internet Explorer in esecuzione, dato il suo PID.

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;
}

Quello che faccio è avviare un processo explorer.exe tramite CreateProcess e quindi utilizzare la funzione sopra per recuperare IWebBrowser2Ptr (in modo da poter giocherellare con il browser).

Sfortunatamente, questo non sembra più funzionare con Internet Explorer 8, poiché IE8 sembra riutilizzare i processi - almeno in una certa misura. Per due sequenze di codici come:

PROCESS_INFORMATION pi;
// ...

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

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

La prima esecuzione di questo codice funziona correttamente, la seconda non riesce mai a recuperare la finestra di pWebBrowser.

Dopo un po 'di debug, è stato rivelato che la funzione findBrowserByPID trova molte finestre del browser (e ne trova altre dopo aver avviato una seconda istanza del browser), ma nessuna di queste appartiene alla nuova processo avviato. Sembra che tutte le finestre appartengano al primo processo di IE avviato.

Qualcuno conosce un modo alternativo per ottenere il puntatore IWebBrowser2 in qualche istanza di IE8? O c'è forse un modo per disabilitare questo apparente "riutilizzo" dei processi con IE8?

È stato utile?

Soluzione

Se stai avviando tu stesso il processo IE, non usare CreateProcess, invece usa CoCreateInstance. Ciò restituirà un oggetto per il quale è possibile eseguire una query per IWebBrowser2, che è possibile utilizzare a piacimento. L'unica complessità è che se la navigazione attraversa i livelli di integrità (Vista +) il puntatore diventa non valido. Per risolvere il problema, sincronizza l'evento NewProcess, che ti permetterà di rilevare questa condizione.

Altre informazioni qui: http: / /msdn.microsoft.com/en-us/library/aa752084%28VS.85%29.aspx

Altri suggerimenti

Un paio di approcci alternativi potrebbero essere:

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top