chrome_process_finder_win.cc 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // Copyright 2013 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "chrome/browser/chrome_process_finder_win.h"
  5. #include <shellapi.h>
  6. #include <string>
  7. #include "base/command_line.h"
  8. #include "base/files/file_path.h"
  9. #include "base/files/file_util.h"
  10. #include "base/logging.h"
  11. #include "base/process/process.h"
  12. #include "base/process/process_info.h"
  13. #include "base/strings/string_number_conversions.h"
  14. #include "base/strings/stringprintf.h"
  15. #include "base/strings/utf_string_conversions.h"
  16. #include "base/win/message_window.h"
  17. #include "base/win/scoped_handle.h"
  18. #include "base/win/win_util.h"
  19. #include "base/win/windows_version.h"
  20. namespace {
  21. int timeout_in_milliseconds = 20 * 1000;
  22. } // namespace
  23. namespace chrome {
  24. HWND FindRunningChromeWindow(const base::FilePath& user_data_dir) {
  25. return base::win::MessageWindow::FindWindow(user_data_dir.value());
  26. }
  27. NotifyChromeResult AttemptToNotifyRunningChrome(HWND remote_window,
  28. bool fast_start) {
  29. DCHECK(remote_window);
  30. DWORD process_id = 0;
  31. DWORD thread_id = GetWindowThreadProcessId(remote_window, &process_id);
  32. if (!thread_id || !process_id)
  33. return NOTIFY_FAILED;
  34. // Send the command line to the remote chrome window.
  35. // Format is "START\0<<<current directory>>>\0<<<commandline>>>".
  36. std::wstring to_send(L"START\0", 6); // want the NULL in the string.
  37. base::FilePath cur_dir;
  38. if (!base::GetCurrentDirectory(&cur_dir))
  39. return NOTIFY_FAILED;
  40. to_send.append(cur_dir.value());
  41. to_send.append(L"\0", 1); // Null separator.
  42. to_send.append(::GetCommandLineW());
  43. to_send.append(L"\0", 1); // Null separator.
  44. // Allow the current running browser window to make itself the foreground
  45. // window (otherwise it will just flash in the taskbar).
  46. ::AllowSetForegroundWindow(process_id);
  47. COPYDATASTRUCT cds;
  48. cds.dwData = 0;
  49. cds.cbData = static_cast<DWORD>((to_send.length() + 1) * sizeof(wchar_t));
  50. cds.lpData = const_cast<wchar_t*>(to_send.c_str());
  51. DWORD_PTR result = 0;
  52. if (::SendMessageTimeout(remote_window, WM_COPYDATA, NULL,
  53. reinterpret_cast<LPARAM>(&cds), SMTO_ABORTIFHUNG,
  54. timeout_in_milliseconds, &result)) {
  55. return result ? NOTIFY_SUCCESS : NOTIFY_FAILED;
  56. }
  57. // It is possible that the process owning this window may have died by now.
  58. if (!::IsWindow(remote_window))
  59. return NOTIFY_FAILED;
  60. // If the window couldn't be notified but still exists, assume it is hung.
  61. return NOTIFY_WINDOW_HUNG;
  62. }
  63. base::TimeDelta SetNotificationTimeoutForTesting(base::TimeDelta new_timeout) {
  64. base::TimeDelta old_timeout =
  65. base::TimeDelta::FromMilliseconds(timeout_in_milliseconds);
  66. timeout_in_milliseconds = new_timeout.InMilliseconds();
  67. return old_timeout;
  68. }
  69. } // namespace chrome