Pregunta

hasta ahora, he utilizado con éxito la siguiente función para recuperar el puntero IWebBrowser2 a una instancia de Internet Explorer en ejecución, dado que es 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;
}

Lo que hago es iniciar un proceso explorer.exe a través de CreateProcess y luego usar la función anterior para recuperar IWebBrowser2Ptr (para que pueda jugar con el navegador).

Desafortunadamente, esto ya no parece funcionar con Internet Explorer 8, ya que IE8 parece reutilizar procesos, al menos hasta cierto punto. Para dos secuencias de código como:

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 primera ejecución de este código funciona bien, la segunda nunca logra recuperar la ventana pWebBrowser.

Después de un poco de depuración, se reveló que la función findBrowserByPID encuentra muchas ventanas del navegador (y encuentra más después de iniciar una segunda instancia del navegador), pero ninguna de ellas pertenece al nuevo proceso iniciado Parece que todas las ventanas pertenecen al primer proceso de IE que se inició.

¿Alguien sabe una forma alternativa de obtener el puntero IWebBrowser2 a alguna instancia de IE8? ¿O tal vez hay una manera de desactivar esta aparente 'reutilización' de procesos con IE8?

¿Fue útil?

Solución

Si está iniciando el proceso de IE usted mismo, no use CreateProcess; en su lugar, use CoCreateInstance. Eso le devolverá un objeto para el que puede consultar IWebBrowser2, que puede usar a voluntad. La única complejidad es que si la navegación cruza los niveles de integridad (Vista +), el puntero se vuelve inválido. Para solucionar ese problema, sincronice el evento NewProcess, que le permitirá detectar esta condición.

Vea más información aquí: http: / /msdn.microsoft.com/en-us/library/aa752084%28VS.85%29.aspx

Otros consejos

Un par de enfoques alternativos pueden ser:

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top