diff options
author | kuchhal@chromium.org <kuchhal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-11-07 01:27:57 +0000 |
---|---|---|
committer | kuchhal@chromium.org <kuchhal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-11-07 01:27:57 +0000 |
commit | 2414e84fdc99feb8e3a674a1776cddf5d24529fd (patch) | |
tree | a7735239d78bdbc37dcaf5a6428b3076d8a5ff33 /chrome/installer/setup | |
parent | 0c294877146c3812e0a69a5a6ec0cf3e29803954 (diff) | |
download | chromium_src-2414e84fdc99feb8e3a674a1776cddf5d24529fd.zip chromium_src-2414e84fdc99feb8e3a674a1776cddf5d24529fd.tar.gz chromium_src-2414e84fdc99feb8e3a674a1776cddf5d24529fd.tar.bz2 |
Implement the new mechanism we are going to use for handling Chromium updates
while it is in use. This should work for per user as well as system level
installs (after some additional changes once Google Update changes are ready).
The following scenarios should work now:
- If Chromium is using two different profiles at the same time we do not switch
chrome executables until all of them are closed.
- The old version of Chromium can be run after a restart if the renaming of
executables fails.
- We will not use environment variable any more but we need to keep it until all
the users get this change on their machines.
- opv/rename registry keys and new_chrome.exe should always together. If one
exist all three should exist because they are created and deleted as one atomic
operation (as much as possible given laws of physics).
BUG=1463346
Review URL: http://codereview.chromium.org/9436
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@4949 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/installer/setup')
-rw-r--r-- | chrome/installer/setup/install.cc | 74 | ||||
-rwxr-xr-x[-rw-r--r--] | chrome/installer/setup/main.cc | 54 | ||||
-rw-r--r-- | chrome/installer/setup/setup_constants.cc | 2 | ||||
-rw-r--r-- | chrome/installer/setup/setup_constants.h | 2 |
4 files changed, 118 insertions, 14 deletions
diff --git a/chrome/installer/setup/install.cc b/chrome/installer/setup/install.cc index 34429b3..b051f82 100644 --- a/chrome/installer/setup/install.cc +++ b/chrome/installer/setup/install.cc @@ -5,13 +5,16 @@ #include <time.h> #include "base/file_util.h" +#include "base/registry.h" #include "base/scoped_ptr.h" #include "base/string_util.h" #include "chrome/installer/setup/setup.h" #include "chrome/installer/setup/setup_constants.h" #include "chrome/installer/util/browser_distribution.h" #include "chrome/installer/util/google_update_constants.h" +#include "chrome/installer/util/set_reg_value_work_item.h" #include "chrome/installer/util/shell_util.h" +#include "chrome/installer/util/work_item.h" namespace { std::wstring AppendPath(const std::wstring parent_path, @@ -154,13 +157,22 @@ bool installer::InstallNewVersion(const std::wstring& exe_path, // Delete any new_chrome.exe if present (we will end up create a new one // if required) and then copy chrome.exe - install_list->AddDeleteTreeWorkItem( - AppendPath(install_path, installer::kChromeNewExe), std::wstring()); + std::wstring new_chrome_exe = AppendPath(install_path, + installer_util::kChromeNewExe); + BrowserDistribution* dist = BrowserDistribution::GetDistribution(); + RegKey chrome_key(reg_root, dist->GetVersionKey().c_str(), + KEY_READ | KEY_WRITE); + std::wstring current_version; + if (file_util::PathExists(new_chrome_exe)) + chrome_key.ReadValue(google_update::kRegOldVersionField, ¤t_version); + if (current_version.empty()) + chrome_key.ReadValue(google_update::kRegVersionField, ¤t_version); + + install_list->AddDeleteTreeWorkItem(new_chrome_exe, std::wstring()); install_list->AddCopyTreeWorkItem( AppendPath(src_path, installer_util::kChromeExe), AppendPath(install_path, installer_util::kChromeExe), - temp_dir, WorkItem::RENAME_IF_IN_USE, - AppendPath(install_path, installer::kChromeNewExe)); + temp_dir, WorkItem::NEW_NAME_IF_IN_USE, new_chrome_exe); // Extra executable for 64 bit systems. if (Is64bit()) { @@ -180,14 +192,13 @@ bool installer::InstallNewVersion(const std::wstring& exe_path, // add shortcut in Control Panel->Add/Remove Programs. AddInstallerCopyTasks(exe_path, archive_path, temp_dir, install_path, new_version.GetString(), install_list.get()); - BrowserDistribution* dist = BrowserDistribution::GetDistribution(); std::wstring product_name = dist->GetApplicationName(); AddUninstallShortcutWorkItems(reg_root, exe_path, install_path, product_name, new_version.GetString(), install_list.get()); // Delete any old_chrome.exe if present. install_list->AddDeleteTreeWorkItem( - AppendPath(install_path, installer::kChromeOldExe), std::wstring()); + AppendPath(install_path, installer_util::kChromeOldExe), std::wstring()); // Create Version key (if not already present) and set the new Chrome // version as last step. @@ -203,13 +214,56 @@ bool installer::InstallNewVersion(const std::wstring& exe_path, true); // overwrite version // Perform install operations. - if (!install_list->Do()) { + bool success = install_list->Do(); + + // If the installation worked, handle the in-use update case: + // * If new_chrome.exe exists, then currently Chrome was in use so save + // current version in old version key. + // * If new_chrome.exe doesnt exist, then delete old version key. + if (success) { + if (file_util::PathExists(new_chrome_exe)) { + if (current_version.empty()) { + LOG(ERROR) << "New chrome.exe exists but current version is empty!"; + success = false; + } else { + scoped_ptr<WorkItemList> inuse_list(WorkItem::CreateWorkItemList()); + inuse_list->AddSetRegValueWorkItem(reg_root, + version_key, + google_update::kRegOldVersionField, + current_version.c_str(), + true); + std::wstring rename_cmd(installer::GetInstallerPathUnderChrome( + install_path, new_version.GetString())); + file_util::AppendToPath(&rename_cmd, + file_util::GetFilenameFromPath(exe_path)); + rename_cmd = L"\"" + rename_cmd + L"\" --" + + installer_util::switches::kRenameChromeExe; + inuse_list->AddSetRegValueWorkItem(reg_root, + version_key, + google_update::kRegRenameCmdField, + rename_cmd.c_str(), + true); + if (!inuse_list->Do()) { + LOG(ERROR) << "Couldn't write old version/rename value to registry."; + success = false; + inuse_list->Rollback(); + } + } + } else { + if (chrome_key.ValueExists(google_update::kRegOldVersionField) && + !chrome_key.DeleteValue(google_update::kRegOldVersionField)) { + LOG(ERROR) << "New chrome.exe doesn't exist but failed to delete " + << "old version value in registry."; + success = false; + } + } + } + + if (!success) { LOG(ERROR) << "Install failed, rolling back... "; install_list->Rollback(); LOG(ERROR) << "Rollback complete. "; - return false; } - - return true; + return success; } diff --git a/chrome/installer/setup/main.cc b/chrome/installer/setup/main.cc index 57730e3..730f4ff 100644..100755 --- a/chrome/installer/setup/main.cc +++ b/chrome/installer/setup/main.cc @@ -161,6 +161,55 @@ installer::Version* GetVersionFromDir(const std::wstring& chrome_path) { return version; } +// This function is called when --rename-chrome-exe option is specified on +// setup.exe command line. This function assumes an in-use update has happened +// for Chrome so there should be a file called new_chrome.exe on the file +// system and a key called 'opv' in the registry. This function will move +// new_chrome.exe to chrome.exe and delete 'opv' key in one atomic operation. +installer_util::InstallStatus RenameChromeExecutables(bool system_install) { + std::wstring chrome_path(installer::GetChromeInstallPath(system_install)); + + std::wstring chrome_exe(chrome_path); + file_util::AppendToPath(&chrome_exe, installer_util::kChromeExe); + std::wstring chrome_old_exe(chrome_path); + file_util::AppendToPath(&chrome_old_exe, installer_util::kChromeOldExe); + std::wstring chrome_new_exe(chrome_path); + file_util::AppendToPath(&chrome_new_exe, installer_util::kChromeNewExe); + + scoped_ptr<WorkItemList> install_list(WorkItem::CreateWorkItemList()); + install_list->AddDeleteTreeWorkItem(chrome_old_exe, std::wstring()); + std::wstring temp_path; + if (!file_util::CreateNewTempDirectory(std::wstring(L"chrome_"), + &temp_path)) { + LOG(ERROR) << "Failed to create Temp directory " << temp_path; + return installer_util::RENAME_FAILED; + } + install_list->AddCopyTreeWorkItem(chrome_new_exe, + chrome_exe, + temp_path, + WorkItem::IF_DIFFERENT, + std::wstring()); + HKEY reg_root = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; + BrowserDistribution *dist = BrowserDistribution::GetDistribution(); + install_list->AddDeleteRegValueWorkItem(reg_root, + dist->GetVersionKey(), + google_update::kRegOldVersionField, + true); + install_list->AddDeleteTreeWorkItem(chrome_new_exe, std::wstring()); + install_list->AddDeleteRegValueWorkItem(reg_root, + dist->GetVersionKey(), + google_update::kRegRenameCmdField, + true); + installer_util::InstallStatus ret = installer_util::RENAME_SUCCESSFUL; + if (!install_list->Do()) { + LOG(ERROR) << "Renaming of executables failed. Rolling back any changes."; + install_list->Rollback(); + ret = installer_util::RENAME_FAILED; + } + file_util::Delete(temp_path, true); + return ret; +} + // Parse command line and read master profile, if present, to get distribution // related install options. int GetInstallOptions(const CommandLine& cmd_line) { @@ -450,6 +499,11 @@ int WINAPI wWinMain(HINSTANCE instance, HINSTANCE prev_instance, std::wstring chrome_exe(parsed_command_line.GetSwitchValue( installer_util::switches::kRegisterChromeBrowser)); return ShellUtil::AddChromeToSetAccessDefaults(chrome_exe, true); + // If --rename-chrome-exe is specified, we want to rename the executables + // and exit. + } else if (parsed_command_line.HasSwitch( + installer_util::switches::kRenameChromeExe)) { + return RenameChromeExecutables(system_install); } if (system_install && diff --git a/chrome/installer/setup/setup_constants.cc b/chrome/installer/setup/setup_constants.cc index 4240022..a307b44 100644 --- a/chrome/installer/setup/setup_constants.cc +++ b/chrome/installer/setup/setup_constants.cc @@ -6,8 +6,6 @@ namespace installer { // Elements that makes up install target path. -const wchar_t kChromeOldExe[] = L"old_chrome.exe"; -const wchar_t kChromeNewExe[] = L"new_chrome.exe"; const wchar_t kWowHelperExe[] = L"wow_helper.exe"; const wchar_t kDictionaries[] = L"Dictionaries"; const wchar_t kChromeArchive[] = L"chrome.7z"; diff --git a/chrome/installer/setup/setup_constants.h b/chrome/installer/setup/setup_constants.h index b8a90e8..b95d774 100644 --- a/chrome/installer/setup/setup_constants.h +++ b/chrome/installer/setup/setup_constants.h @@ -9,8 +9,6 @@ namespace installer { -extern const wchar_t kChromeOldExe[]; -extern const wchar_t kChromeNewExe[]; extern const wchar_t kWowHelperExe[]; extern const wchar_t kDictionaries[]; extern const wchar_t kChromeArchive[]; |