Вопрос

до сих пор я успешно использовал следующую функцию для получения указателя IWebBrowser2 на работающий экземпляр Internet Explorer, учитывая его 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;
}

Что я делаю, так это запускаю explorer.exe процесс через CreateProcess а затем используйте приведенную выше функцию, чтобы получить к нему IWebBrowser2Ptr (чтобы я мог поиграть с браузером).

К сожалению, похоже, это больше не работает с Internet Explorer 8, поскольку IE8, похоже, повторно использует процессы - по крайней мере, в некоторой степени.Для двух последовательностей кода, например:

PROCESS_INFORMATION pi;
// ...

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

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

Первый запуск этого кода работает нормально, второй никогда не удается получить окно pWebBrowser.

После небольшой отладки выяснилось, что findBrowserByPID Функция находит множество окон браузера (и находит больше после запуска второго экземпляра браузера), но ни одно из них не принадлежит только что запущенному процессу.Кажется, что все окна принадлежат первому запущенному процессу IE.

Кто-нибудь знает альтернативный способ получить указатель IWebBrowser2 на какой-либо экземпляр IE8?Или, может быть, есть способ отключить это очевидное «повторное использование» процессов в IE8?

Это было полезно?

Решение

Если вы запускаете процесс IE самостоятельно, не используйте CreateProcess - вместо этого используйте CoCreateInstance. Это вернет вам объект, для которого вы можете запросить IWebBrowser2, который вы можете использовать по желанию. Одна сложность заключается в том, что если навигация пересекает уровни целостности (Vista +), указатель становится недействительным. Чтобы решить эту проблему, синхронизируйте событие NewProcess, которое позволит вам обнаружить это условие.

Дополнительную информацию см. здесь: http: / /msdn.microsoft.com/en-us/library/aa752084%28VS.85%29.aspx

Другие советы

Несколько альтернативных подходов могут быть:

  • Получить ссылку через HWND

  • Используйте библиотеку типа ВатиН что может помочь вам достичь любой вашей реальной конечной цели, если вы пытаетесь автоматизировать IE.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top