Sinking DWebBrowserEvents2 events appears to hang programmatic navigation

六眼飞鱼酱① 提交于 2019-12-23 05:29:31

问题


I posted this question on the MSDN forums, but my experience has been a better quality of answer here on Stack Overflow, so I'm posting here as well. As I've posted several times before, I'm working on a browser automation framework, automating Internet Explorer from an external process. My architecture is as follows: I have a server which opens a named pipe that my automation client pushes commands to. The server interprets the commands, and executes them on the IWebBrowser2 object, which I have wrapped in my own C++ class. Everything works fine until I try to sink events on the IE instance. My wrapper class implements IDispEventSimpleImpl, but when I try to sink the events, the browser instance doesn't respond to any communication, either programmatically or via the UI. Here are my main two methods with the most relevance:

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;
}

Interestingly, I prototyped this same mechanism in C# before translating it into unmanaged C++ to make sure what I was attempting would work, since my C++ skills are not at the same level as my C# skills. Needless to say, it works fine in C#, but it is a requirement that this component be written in unmanaged code. I'm sure I'm overlooking something obvious that the .NET Framework abstracts away, but whatever it is, it isn't obvious to me.

To help me learn from my mistake, I'd appreciate a pointer to what it is that the .NET Framework is doing to let this work. In the C# version, I'm using a single thread with blocking I/O on the pipe, just like I (think I) am here. If the posted code snippet isn't enough to point toward a diagnosis, I'm more than happy to provide a full Visual Studio 2008 solution demonstrating the difficulty.


回答1:


Your app is becoming a com server by providing event sinks. The com app needs active 'message pump'(s).

If your blocking the message pump while your doing your pipe/dispatch command then it will block IE from calling on your event sink.

C# may work simply for the other hidden windows it has and however you have set up the rest of that app.



来源:https://stackoverflow.com/questions/3919170/sinking-dwebbrowserevents2-events-appears-to-hang-programmatic-navigation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!