我發佈了這個問題在MSDN論壇上,但我的經驗已經在堆棧溢出這裏的答案更好的質量,所以我在這裏發佈。正如我之前幾次發佈的那樣,我正在研究瀏覽器自動化框架,從外部過程中自動化Internet Explorer。我的架構如下:我有一臺服務器,它打開一個命名管道,我的自動化客戶端將命令推送到該管道。服務器解釋這些命令,並在IWebBrowser2對象上執行它們,IWebBrowser2對象已包裝在我自己的C++類中。一切工作正常,直到我試圖吸收事件的IE實例。我的包裝類實現了IDispEventSimpleImpl,但是當我嘗試吸收事件時,瀏覽器實例無法以編程方式或通過UI對任何通信作出響應。下面是我的主要兩種方法最相關:下沉DWebBrowserEvents2事件似乎掛起程序化導航
void BrowserManager::Start(void)
{
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
std::basic_string<TCHAR> pipeName =L"\\\\.\\pipe\\managerpipe";
HANDLE hPipe = ::CreateNamedPipe(pipeName.c_str(),
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
PIPE_UNLIMITED_INSTANCES,
1024,
1024,
0,
NULL);
if (hPipe == INVALID_HANDLE_VALUE)
{
DWORD dwError = ::GetLastError();
}
this->m_isRunning = true;
while (this->m_isRunning)
{
BOOL result = ::ConnectNamedPipe(hPipe, NULL);
std::vector<CHAR> inputBuffer(1024);
DWORD bytesRead = 0;
::ReadFile(hPipe, &inputBuffer[0], 1024, &bytesRead, NULL);
std::string command = &inputBuffer[0];
std::string response = DispatchCommand(command);
std::vector<CHAR> outputBuffer(response.begin(), response.end());
::WriteFile(hPipe, &outputBuffer[0], outputBuffer.size(), &bytesRead, NULL);
::FlushFileBuffers(hPipe);
::DisconnectNamedPipe(hPipe);
if (strcmp(command.c_str(), "quit\r\n") == 0)
{
this->m_isRunning = false;
}
}
::CloseHandle(hPipe);
CoUninitialize();
}
std::string BrowserManager::DispatchCommand(std::string command)
{
std::string response;
if (strcmp(command.c_str(), "start\r\n") == 0)
{
// Launch the browser process using CreateProcess on XP
// or IELaunchURL on Vista or higher. This is done on a
// low-integrity thread so we have the correct integrity.
DWORD procId = this->m_factory->LaunchBrowserProcess();
CComPtr<IWebBrowser2> pBrowser(this->m_factory->AttachToBrowser(procId));
BrowserWrapper wrapper(pBrowser);
this->m_wrapper = wrapper;
response = "started";
}
else if (strcmp(command.c_str(), "goto\r\n") == 0)
{
this->m_wrapper.GoToUrl("http://www.google.com/");
response = "navigated";
}
else if (strcmp(command.c_str(), "quit\r\n") == 0)
{
this->m_wrapper.CloseBrowser();
response = "closed";
}
else
{
response = "invalid command";
}
return response;
}
有趣的是,我的原型在C#中同樣的機制轉換成非託管C++之前,爲了確保我試圖將工作,因爲我的C++技能不是在與我的C#技能水平相同。不用說,它在C#中可以正常工作,但是這個組件需要寫入非託管代碼。我敢肯定,我忽視了.NET Framework抽象化的東西,但不管它是什麼,它對我來說都不是顯而易見的。
爲了幫助我從我的錯誤中學習,我會很感激一個指向.NET Framework爲了讓它工作而做的事。在C#版本中,我使用單個線程來阻塞管道上的I/O,就像我在這裏(想我)。如果發佈的代碼片段不足以指向診斷,那麼我很樂意提供一個完整的Visual Studio 2008解決方案來展示難度。
標題提到DWebBrowserEvents2它沒有在代碼中顯示。 – 2010-10-12 22:04:23