gpt4 book ai didi

c++ - 下沉的 DWebBrowserEvents2 事件似乎挂起编程导航

转载 作者:行者123 更新时间:2023-11-28 03:55:05 24 4
gpt4 key购买 nike

我在 MSDN 论坛上发布了这个问题,但我的经验是 Stack Overflow 上的答案质量更好,所以我也在这里发布。正如我之前多次发布的那样,我正在研究浏览器自动化框架,从外部进程自动化 Internet Explorer。我的体系结构如下:我有一个服务器,它打开一个命名管道,我的自动化客户端将命令推送到该管道。服务器解释命令,并在我包装在我自己的 C++ 类中的 IWebBrowser2 对象上执行它们。一切正常,直到我尝试在 IE 实例上接收事件。我的包装器类实现了 IDispEventSimpleImpl,但是当我尝试接收事件时,浏览器实例不会以编程方式或通过 UI 响应任何通信。以下是我最相关的两种主要方法:

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# 中制作了相同机制的原型(prototype),以确保我尝试的内容能够正常工作,因为我的 C++ 技能与我的 C# 技能不在同一水平。不用说,它在 C# 中运行良好,但要求该组件以非托管代码编写。我确信我忽略了 .NET Framework 抽象掉的一些明显的东西,但不管它是什么,对我来说并不明显。

为了帮助我从我的错误中吸取教训,我希望能指出 .NET Framework 正在做些什么来让这项工作发挥作用。在 C# 版本中,我在管道上使用带有阻塞 I/O 的单线程,就像我(认为我)在这里一样。如果发布的代码片段不足以指向诊断,我非常乐意提供一个完整的 Visual Studio 2008 解决方案来展示困难。

最佳答案

您的应用通过提供事件接收器成为一个 com 服务器。 com 应用程序需要事件的“消息泵”。

如果您在执行管道/调度命令时阻止消息泵,那么它将阻止 IE 调用您的事件接收器。

C# 可能只适用于它拥有的其他隐藏窗口,但是您已经设置了该应用程序的其余部分。

关于c++ - 下沉的 DWebBrowserEvents2 事件似乎挂起编程导航,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3919170/

24 4 0
文章推荐: c++ - g++静态库依赖动态库
文章推荐: android - CSS 新手 : CSS not rendering on Android but does render with Visual Studio Ripple Virtual Nexus (Galaxy)
文章推荐: c++ - 我的 openmp 并行编程有什么问题
文章推荐: html - IE z-index 问题。 wmode透明不起作用