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 b1293360a38a62ec16427c4277891f7d72b1fc29..e869d21955cd60f5d4470e5405068c987f1240e3 100644 |
--- a/chrome/browser/first_run/upgrade_util_win.cc |
+++ b/chrome/browser/first_run/upgrade_util_win.cc |
@@ -5,6 +5,7 @@ |
#include "chrome/browser/first_run/upgrade_util.h" |
#include <windows.h> |
+#include <psapi.h> |
#include <shellapi.h> |
#include <algorithm> |
@@ -123,26 +124,30 @@ bool RelaunchChromeHelper(const CommandLine& command_line, |
else |
version_str.clear(); |
- if (base::win::GetVersion() < base::win::VERSION_WIN8) |
- return base::LaunchProcess(command_line, base::LaunchOptions(), NULL); |
- |
- // On Windows 8 we always use the delegate_execute for re-launching chrome. |
- // |
- // Pass this Chrome's Start Menu shortcut path to the relauncher so it can |
- // re-activate chrome via ShellExecute. |
base::FilePath chrome_exe; |
if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { |
NOTREACHED(); |
return false; |
} |
- // We need to use ShellExecute to launch the relauncher, which will wait until |
- // we exit. But ShellExecute does not support handle passing to the child |
- // process so we create a uniquely named mutex that we aquire and never |
- // release. So when we exit, Windows marks our mutex as abandoned and the |
- // wait is satisfied. |
- // The format of the named mutex is important. See DelegateExecuteOperation |
- // for more details. |
+ CommandLine chrome_exe_command_line = command_line; |
grt (UTC plus 2)
2014/05/15 17:47:38
consider:
// Take care to relaunch chrome.exe ra
robertshield
2014/05/15 18:42:30
Done.
|
+ base::FilePath current_exe_path(chrome_exe.DirName()); |
grt (UTC plus 2)
2014/05/15 17:47:38
current_exe_path is a bit misleading. how about do
robertshield
2014/05/15 18:42:30
Done.
|
+ current_exe_path = current_exe_path.Append(installer::kChromeExe); |
+ chrome_exe_command_line.SetProgram(current_exe_path); |
+ |
+ if (base::win::GetVersion() < base::win::VERSION_WIN8) |
+ return base::LaunchProcess(chrome_exe_command_line, |
+ base::LaunchOptions(), NULL); |
+ |
+ // On Windows 8 we always use the delegate_execute for re-launching chrome. |
+ // |
+ // Pass this Chrome's Start Menu shortcut path to the relauncher so it can re- |
+ // activate chrome via ShellExecute which will wait until we exit. Since |
+ // ShellExecute does not support handle passing to the child process we create |
+ // a uniquely named mutex that we aquire and never release. So when we exit, |
+ // Windows marks our mutex as abandoned and the wait is satisfied. The format |
+ // of the named mutex is important. See DelegateExecuteOperation for more |
+ // details. |
base::string16 mutex_name = |
base::StringPrintf(L"chrome.relaunch.%d", ::GetCurrentProcessId()); |
HANDLE mutex = ::CreateMutexW(NULL, TRUE, mutex_name.c_str()); |
@@ -246,13 +251,32 @@ bool SwapNewChromeExeIfPresent() { |
return InvokeGoogleUpdateForRename(); |
} |
+bool IsRunningOldChrome() { |
+ // This figures out the actual file name that the section containing the |
+ // mapped exe refers to. This is used instead of GetModuleFileName because the |
+ // .exe may have been renamed out from under us while we've been running which |
+ // GetModuleFileName won't notice. |
+ wchar_t mapped_file_name[MAX_PATH * 2] = {}; |
+ |
+ if (!::GetMappedFileName(::GetCurrentProcess(), |
+ reinterpret_cast<void*>(::GetModuleHandle(NULL)), |
+ mapped_file_name, |
+ arraysize(mapped_file_name))) { |
+ return false; |
+ } |
+ |
+ base::FilePath file_name(base::FilePath(mapped_file_name).BaseName()); |
+ return base::FilePath::CompareEqualIgnoreCase(file_name.value(), |
+ installer::kChromeOldExe); |
+} |
+ |
bool DoUpgradeTasks(const CommandLine& command_line) { |
// The DelegateExecute verb handler finalizes pending in-use updates for |
// metro mode launches, as Chrome cannot be gracefully relaunched when |
// running in this mode. |
if (base::win::IsMetroProcess()) |
return false; |
- if (!SwapNewChromeExeIfPresent()) |
+ if (!SwapNewChromeExeIfPresent() && !IsRunningOldChrome()) |
return false; |
// At this point the chrome.exe has been swapped with the new one. |
if (!RelaunchChromeBrowser(command_line)) { |