Index: chrome/browser/first_run/upgrade_util_win.cc |
diff --git a/chrome/browser/first_run/upgrade_util_win.cc b/chrome/browser/first_run/upgrade_util_win.cc |
index 834a9790a0fdde336dc60a0e5d1e08fd8ca1ca56..6569562f04492a754345800c38dce59b8f11c784 100644 |
--- a/chrome/browser/first_run/upgrade_util_win.cc |
+++ b/chrome/browser/first_run/upgrade_util_win.cc |
@@ -15,11 +15,13 @@ |
#include "base/logging.h" |
#include "base/path_service.h" |
#include "base/process_util.h" |
+#include "base/string_number_conversions.h" |
#include "base/string_util.h" |
#include "base/win/metro.h" |
#include "base/win/registry.h" |
#include "base/win/scoped_comptr.h" |
#include "chrome/browser/first_run/upgrade_util_win.h" |
+#include "chrome/browser/shell_integration.h" |
#include "chrome/common/chrome_constants.h" |
#include "chrome/common/chrome_switches.h" |
#include "chrome/installer/util/browser_distribution.h" |
@@ -60,14 +62,70 @@ bool InvokeGoogleUpdateForRename() { |
return false; |
} |
+FilePath GetMetroRelauncherPath(const FilePath& chrome_exe, |
+ const std::string version_str) { |
+ FilePath path(chrome_exe.DirName()); |
+ |
+ // The relauncher is ordinarily in the version directory. When running in a |
+ // build tree however (where CHROME_VERSION is not set in the environment) |
+ // look for it in Chrome's directory. |
+ if (!version_str.empty()) |
+ path = path.AppendASCII(version_str); |
+ |
+ return path.Append(installer::kDelegateExecuteExe); |
+} |
+ |
} // namespace |
namespace upgrade_util { |
bool RelaunchChromeBrowser(const CommandLine& command_line) { |
scoped_ptr<base::Environment> env(base::Environment::Create()); |
- env->UnSetVar(chrome::kChromeVersionEnvVar); |
- return base::LaunchProcess(command_line, base::LaunchOptions(), NULL); |
+ std::string version_str; |
+ |
+ // Get the version variable and remove it from the environment. |
+ if (env->GetVar(chrome::kChromeVersionEnvVar, &version_str)) |
+ env->UnSetVar(chrome::kChromeVersionEnvVar); |
+ else |
+ version_str.clear(); |
+ |
+ if (!base::win::IsMetroProcess()) |
+ return base::LaunchProcess(command_line, base::LaunchOptions(), NULL); |
+ |
+ // Pass this Chrome's Start Menu shortcut path and handle to the relauncher. |
+ // The relauncher will wait for this Chrome to exit then reactivate it by |
+ // way of the Start Menu shortcut. |
+ FilePath chrome_exe; |
+ if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { |
+ NOTREACHED(); |
+ return false; |
+ } |
+ |
+ // Get a handle to this process that can be passed to the relauncher. |
+ HANDLE current_process = GetCurrentProcess(); |
+ base::win::ScopedHandle process_handle; |
+ if (!::DuplicateHandle(current_process, current_process, current_process, |
+ process_handle.Receive(), SYNCHRONIZE, TRUE, 0)) { |
+ DPCHECK(false); |
+ return false; |
+ } |
+ |
+ // Make the command line for the relauncher. |
+ CommandLine relaunch_cmd(GetMetroRelauncherPath(chrome_exe, version_str)); |
+ relaunch_cmd.AppendSwitchPath(switches::kRelaunchShortcut, |
+ ShellIntegration::GetStartMenuShortcut(chrome_exe)); |
+ relaunch_cmd.AppendSwitchNative(switches::kWaitForHandle, |
+ base::UintToString16(reinterpret_cast<uint32>(process_handle.Get()))); |
+ |
+ base::LaunchOptions launch_options; |
+ launch_options.inherit_handles = true; |
+ if (!base::LaunchProcess(relaunch_cmd, launch_options, NULL)) { |
+ DPLOG(ERROR) << "Failed to launch relauncher \"" |
+ << relaunch_cmd.GetCommandLineString() << "\""; |
+ return false; |
+ } |
+ |
+ return true; |
} |
bool IsUpdatePendingRestart() { |