【发布时间】:2011-06-27 23:39:28
【问题描述】:
我正在开发一个browser automation framework,它可以自动化 Internet Explorer 以及其他浏览器。尝试启动 IE 时遇到间歇性问题。如果存在,框架使用 IELaunchURL API 启动 IE,如果不存在则使用 CreateProcess。获取IWebBrowser2接口的代码如下:
// hwndBrowser is obtained by calling ::EnumWindows() with a function that
// compares the process ID of the window handle to the known process ID of
// the IE instance.
CComPtr<IHTMLDocument2> document;
LRESULT result;
::SendMessageTimeout(hwndBrowser,
WM_HTML_GETOBJECT,
0L,
0L,
SMTO_ABORTIFHUNG,
1000,
(PDWORD_PTR)&result);
// oleacc_instance_handle is obtained from ::LoadLibrary("oleacc.dll")
LPFNOBJECTFROMLRESULT object_pointer = reinterpret_cast<LPFNOBJECTFROMLRESULT>(
::GetProcAddress(oleacc_instance_handle, "ObjectFromLresult"));
if (object_pointer != NULL) {
HRESULT hr = (*object_pointer)(result,
IID_IHTMLDocument2,
0,
reinterpret_cast<void **>(&document));
if (SUCCEEDED(hr)) {
CComPtr<IHTMLWindow2> window;
hr = document->get_parentWindow(&window);
if (SUCCEEDED(hr)) {
// http://support.microsoft.com/kb/257717
CComQIPtr<IServiceProvider> provider(window);
if (provider) {
CComPtr<IServiceProvider> child_provider;
hr = provider->QueryService(SID_STopLevelBrowser,
IID_IServiceProvider,
reinterpret_cast<void **>(&child_provider));
if (SUCCEEDED(hr)) {
IWebBrowser2* browser;
hr = child_provider->QueryService(SID_SWebBrowserApp,
IID_IWebBrowser2,
reinterpret_cast<void **>(&browser));
if (SUCCEEDED(hr)) {
// The IWebBrowser2 pointer is passed back to the caller.
// process_window_info->pBrowser = browser;
}
}
}
}
}
}
现在的问题是:似乎我们总能成功地检索到 IHTMLDocument2 对象。但是,当我们尝试调用 get_parentWindow() 时,有时会收到“类未注册”结果 (0x80040154 REGDB_E_CLASSNOTREG),最常见的是在关闭前一个实例后启动 IE 的新实例时。我们可以通过省略对 get_parentWindow() 的调用并直接在文档上调用 QueryService 来获得 IWebBrowser2 接口,但是当我们尝试操作文档的某些部分时,我们会在后面收到这个错误。什么可能导致 get_parentWindow() 调用失败?
请注意,整个代码可以在上下文 here 中找到。
【问题讨论】:
标签: c++ internet-explorer com automation