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 a4fc3b06d9ef4fed983f222b59aab8d4bd6d59bc..ab44092a9bc736ff0c8f5e1807b8e138ea0fc5ee 100644 |
--- a/chrome/browser/first_run/upgrade_util_win.cc |
+++ b/chrome/browser/first_run/upgrade_util_win.cc |
@@ -14,7 +14,9 @@ |
#include "base/file_util.h" |
#include "base/logging.h" |
#include "base/path_service.h" |
+#include "base/process.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" |
@@ -60,14 +62,70 @@ bool InvokeGoogleUpdateForRename() { |
return false; |
} |
+FilePath GetRelauncherPath(base::Environment* env, |
cpu_(ooo_6.6-7.5)
2012/06/29 21:32:39
needs a better name, like GetMetroRelauncherPath
grt (UTC plus 2)
2012/07/31 21:44:03
Done.
|
+ const FilePath& chrome_exe) { |
+ std::string version_str; |
+ |
cpu_(ooo_6.6-7.5)
2012/06/29 21:32:39
kill this empty line
grt (UTC plus 2)
2012/07/31 21:44:03
Done.
|
+ 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 (env->GetVar(chrome::kChromeVersionEnvVar, &version_str)) |
+ 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); |
+ |
+ if (!base::win::IsMetroProcess()) { |
+ env->UnSetVar(chrome::kChromeVersionEnvVar); |
+ return base::LaunchProcess(command_line, base::LaunchOptions(), NULL); |
+ } |
+ |
+ // Pass this Chrome's handle and AppUserModelID to the relauncher. The |
+ // relauncher will wait for this Chrome to exit then reactivate it. |
+ 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(GetRelauncherPath(env.get(), chrome_exe)); |
+ relaunch_cmd.AppendSwitchNative(switches::kActivateApp, |
+ ShellUtil::GetBrowserModelId(BrowserDistribution::GetDistribution(), |
+ chrome_exe.value())); |
+ relaunch_cmd.AppendSwitchNative(switches::kWaitForHandle, |
+ base::PointerToString16(process_handle.Get())); |
+ |
+ // Relaunch. |
+ 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; |
+ } |
+ |
+ // Ownership of the duplicated handle has been passed to the child process. |
+ ignore_result(process_handle.Take()); |
grt (UTC plus 2)
2012/07/31 21:44:03
It's my understanding that both processes need to
|
+ return true; |
} |
bool IsUpdatePendingRestart() { |