Pergunta

até agora, eu usei com sucesso a seguinte função para recuperar o ponteiro IWebBrowser2 para uma instância do Internet Explorer em execução, dado que é 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;
}

O que eu faço é lançar um processo explorer.exe via CreateProcess e, em seguida, usar a função acima para recuperar o IWebBrowser2Ptr a ele (para que eu possa mexer com o navegador).

Infelizmente, isso não parece funcionar com o Internet Explorer 8 mais, desde IE8 parece processos de reutilização - pelo menos em algum grau. Por duas seqüências 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 );
}

A primeira execução deste código funciona bem, o segundo nunca consegue recuperar a janela de pWebBrowser.

Depois de um pouco de depuração, foi revelado que a função findBrowserByPID faz encontrar muitas janelas do navegador (e ele encontrar mais depois de iniciar uma segunda instância do navegador), mas nenhum deles pertencem ao processo recém-iniciado. Parece que todas as janelas pertencem ao primeiro processo de IE que foi iniciado.

Alguém sabe uma maneira alternativa de obter o ponteiro IWebBrowser2 para alguma instância IE8? Ou há talvez uma maneira de desativar esse 'reutilização' aparente de processos com IE8?

Foi útil?

Solução

Se você está lançando o IE processo de si mesmo, não use CreateProcess-- em vez disso, o uso CoCreateInstance. Isso irá retornar um objeto para o qual você pode consultar para IWebBrowser2, que você pode usar à vontade. A única complexidade é que se a navegação atravessa níveis de integridade (Vista +) o ponteiro torna-se inválido. Para resolver esse problema, sincronize o evento NewProcess, o que lhe permitirá detectar essa condição.

Veja mais algumas informações aqui: http: / /msdn.microsoft.com/en-us/library/aa752084%28VS.85%29.aspx

Outras dicas

Um par de abordagens alternativas podem ser:

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top