Example #1
0
void IESession::ShutDown(void) {
  LOG(TRACE) << "Entering IESession::ShutDown";

  // Kill the background thread first - otherwise the IE process crashes.
  stopPersistentEventFiring();

  // Don't terminate the thread until the browsers have all been deallocated.
  int is_quitting = static_cast<int>(::SendMessage(this->executor_window_handle_,
                                                   WD_GET_QUIT_STATUS,
                                                   NULL,
                                                   NULL));
  int retry_count = 50;
  while (is_quitting > 0 && --retry_count > 0) {
    ::Sleep(100);
    is_quitting = static_cast<int>(::SendMessage(this->executor_window_handle_,
                                                 WD_GET_QUIT_STATUS,
                                                 NULL,
                                                 NULL));
  }

  DWORD process_id;
  DWORD thread_id = ::GetWindowThreadProcessId(this->executor_window_handle_,
                                               &process_id);
  HANDLE thread_handle = ::OpenThread(SYNCHRONIZE, FALSE, thread_id);
  ::SendMessage(this->executor_window_handle_, WM_CLOSE, NULL, NULL);
  if (thread_handle != NULL) {
    DWORD wait_result = ::WaitForSingleObject(thread_handle, 30000);
    if (wait_result != WAIT_OBJECT_0) {
      LOG(DEBUG) << "Waiting for thread to end returned " << wait_result;
    }
    ::CloseHandle(thread_handle);
  }
}
Example #2
0
void IESession::ShutDown(void) {
  LOG(TRACE) << "Entering IESession::ShutDown";

  // Kill the background thread first - otherwise the IE process crashes.
  stopPersistentEventFiring();

  // Don't terminate the thread until the browsers have all been deallocated.
  // Note: Loop count of 6, because the timeout is 5 seconds, giving us a nice,
  // round 30 seconds.
  int retry_count = 6;
  bool has_quit = this->WaitForCommandExecutorExit(EXECUTOR_EXIT_WAIT_TIMEOUT);
  while (!has_quit && retry_count > 0) {
    // ASSUMPTION! If all browsers haven't been deallocated by the timeout
    // specified, they're blocked from quitting by something. We'll assume
    // that something is an alert blocking close, and ask the executor to
    // attempt another close after closing the offending alert.
    // N.B., this could probably be made more robust by modifying
    // IECommandExecutor::OnGetQuitStatus(), but that would require some
    // fairly complex synchronization code, to make sure a browser isn't
    // deallocated while the "close the alert and close the browser again"
    // code is still running, since the deallocation happens in response
    // to the DWebBrowserEvents2::OnQuit event.
    LOG(DEBUG) << "Not all browsers have been deallocated!";
    ::PostMessage(this->executor_window_handle_,
                  WD_HANDLE_UNEXPECTED_ALERTS,
                  NULL,
                  NULL);
    has_quit = this->WaitForCommandExecutorExit(EXECUTOR_EXIT_WAIT_TIMEOUT);
    retry_count--;
  }

  if (has_quit) {
    LOG(DEBUG) << "Executor shutdown successful!";
  } else {
    LOG(ERROR) << "Still running browsers after handling alerts! This is likely to lead to a crash.";
  }
  DWORD process_id;
  DWORD thread_id = ::GetWindowThreadProcessId(this->executor_window_handle_,
                                               &process_id);
  HANDLE thread_handle = ::OpenThread(SYNCHRONIZE, FALSE, thread_id);
  LOG(DEBUG) << "Posting thread shutdown message";
  ::PostThreadMessage(thread_id, WD_SHUTDOWN, NULL, NULL);
  if (thread_handle != NULL) {
    LOG(DEBUG) << "Starting wait for thread completion";
    DWORD wait_result = ::WaitForSingleObject(&thread_handle, 30000);
    if (wait_result != WAIT_OBJECT_0) {
      LOG(DEBUG) << "Waiting for thread to end returned " << wait_result;
    } else {
      LOG(DEBUG) << "Wait for thread handle complete";
    }
    ::CloseHandle(thread_handle);
  }
}
int IECommandExecutor::CreateNewBrowser(std::string* error_message) {
  LOG(TRACE) << "Entering IECommandExecutor::CreateNewBrowser";

  vector<char> port_buffer(10);
  _itoa_s(this->port_, &port_buffer[0], 10, 10);
  std::string port(&port_buffer[0]);

  std::string initial_url = this->initial_browser_url_;
  if (this->initial_browser_url_ == "") {
    initial_url = "http://localhost:" + port + "/";
  }

  DWORD process_id = this->factory_.LaunchBrowserProcess(initial_url,
      this->ignore_protected_mode_settings_, error_message);
  if (process_id == NULL) {
    LOG(WARN) << "Unable to launch browser, received NULL process ID";
    this->is_waiting_ = false;
    return ENOSUCHDRIVER;
  }

  ProcessWindowInfo process_window_info;
  process_window_info.dwProcessId = process_id;
  process_window_info.hwndBrowser = NULL;
  process_window_info.pBrowser = NULL;
  bool attached = this->factory_.AttachToBrowser(&process_window_info,
                                                 this->browser_attach_timeout_,
                                                 this->ignore_zoom_setting_,
                                                 error_message);
  if (!attached) { 
    LOG(WARN) << "Unable to attach to browser COM object";
    this->is_waiting_ = false;
    return ENOSUCHDRIVER;
  }
  // Set persistent hover functionality in the interactions implementation. 
  setEnablePersistentHover(this->enable_persistent_hover_);
  LOG(INFO) << "Persistent hovering set to: " << this->enable_persistent_hover_;
  if (!this->enable_persistent_hover_) {
    LOG(INFO) << "Stopping previously-running persistent event thread.";
    stopPersistentEventFiring();
  }

  BrowserHandle wrapper(new Browser(process_window_info.pBrowser,
                                    process_window_info.hwndBrowser,
                                    this->m_hWnd));

  this->AddManagedBrowser(wrapper);
  return WD_SUCCESS;
}
Example #4
0
void IESession::ShutDown(void) {
  LOG(TRACE) << "Entering IESession::ShutDown";

  // Kill the background thread first - otherwise the IE process crashes.
  stopPersistentEventFiring();

  DWORD process_id;
  DWORD thread_id = ::GetWindowThreadProcessId(this->executor_window_handle_,
                                               &process_id);
  HANDLE thread_handle = ::OpenThread(SYNCHRONIZE, FALSE, thread_id);
  ::SendMessage(this->executor_window_handle_, WM_CLOSE, NULL, NULL);
  if (thread_handle != NULL) {
    DWORD wait_result = ::WaitForSingleObject(thread_handle, 30000);
    if (wait_result != WAIT_OBJECT_0) {
      LOG(DEBUG) << "Waiting for thread to end returned " << wait_result;
    }
    ::CloseHandle(thread_handle);
  }
}