diff options
author | robertshield@chromium.org <robertshield@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-07 17:27:46 +0000 |
---|---|---|
committer | robertshield@chromium.org <robertshield@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-07 17:27:46 +0000 |
commit | cdc038860e32bfeff7e8e8839deaa1f1185a1373 (patch) | |
tree | 496bedf827fc608688267540f3b9715449605629 /chrome/installer/setup | |
parent | 8784578d7e13d112fd205d3ee4fc1fe0018beea0 (diff) | |
download | chromium_src-cdc038860e32bfeff7e8e8839deaa1f1185a1373.zip chromium_src-cdc038860e32bfeff7e8e8839deaa1f1185a1373.tar.gz chromium_src-cdc038860e32bfeff7e8e8839deaa1f1185a1373.tar.bz2 |
Fix a couple of issues with MSI support through upgrades:
1) When installing from an msi, remove any uninstall shortcuts currently present for that type (system/per-user) of install.
2) When uninstalling, proactively delete the MSI marker from the Omaha ClientState key to avoid an uninstall-reinstall scenario which can cause a reinstall of a non-msi build to be tagged as being msi-managed.
BUG=45252,45273
TEST=Install non-MSI GCF, then install MSI GCF. Observe only a single ARP dialog entry. Then uninstall MSI GCF and quickly reinstall non-MSI GCF, again observe a single ARP dialog entry.
Review URL: http://codereview.chromium.org/2459003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@49069 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/installer/setup')
-rw-r--r-- | chrome/installer/setup/install.cc | 43 | ||||
-rw-r--r-- | chrome/installer/setup/uninstall.cc | 59 |
2 files changed, 62 insertions, 40 deletions
diff --git a/chrome/installer/setup/install.cc b/chrome/installer/setup/install.cc index cdeb22b..f2d2e60 100644 --- a/chrome/installer/setup/install.cc +++ b/chrome/installer/setup/install.cc @@ -205,6 +205,44 @@ void AddUninstallShortcutWorkItems(HKEY reg_root, } } +// This is called when an MSI installation is run. It may be that a user is +// attempting to install the MSI on top of a non-MSI managed installation. +// If so, try and remove any existing uninstallation shortcuts, as we want the +// uninstall to be managed entirely by the MSI machinery (accessible via the +// Add/Remove programs dialog). +void DeleteUninstallShortcutsForMSI(bool is_system_install) { + DCHECK(InstallUtil::IsMSIProcess(is_system_install)) + << "This must only be called for MSI installations!"; + + // First attempt to delete the old installation's ARP dialog entry. + HKEY reg_root = is_system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; + RegKey root_key(reg_root, L"", KEY_ALL_ACCESS); + BrowserDistribution* dist = BrowserDistribution::GetDistribution(); + std::wstring uninstall_reg = dist->GetUninstallRegPath(); + InstallUtil::DeleteRegistryKey(root_key, uninstall_reg); + + // Then attempt to delete the old installation's start menu shortcut. + FilePath uninstall_link; + if (is_system_install) { + PathService::Get(base::DIR_COMMON_START_MENU, &uninstall_link); + } else { + PathService::Get(base::DIR_START_MENU, &uninstall_link); + } + if (uninstall_link.empty()) { + LOG(ERROR) << "Failed to get location for shortcut."; + } else { + BrowserDistribution* dist = BrowserDistribution::GetDistribution(); + uninstall_link = uninstall_link.Append(dist->GetAppShortCutName()); + uninstall_link = uninstall_link.Append( + dist->GetUninstallLinkName() + L".lnk"); + LOG(INFO) << "Deleting old uninstall shortcut (if present):" + << uninstall_link.value(); + if (!file_util::Delete(uninstall_link, true)) { + LOG(INFO) << "Failed to delete old uninstall shortcut."; + } + } +} + // Copy master preferences file provided to installer, in the same folder // as chrome.exe so Chrome first run can find it. This function will be called // only on the first install of Chrome. @@ -460,6 +498,11 @@ bool DoPostInstallTasks(HKEY reg_root, if (InstallUtil::IsMSIProcess(is_system_install)) { if (!InstallUtil::SetMSIMarker(is_system_install, true)) return false; + + // We want MSI installs to take over the Add/Remove Programs shortcut. Make + // a best-effort attempt to delete any shortcuts left over from previous + // non-MSI installations for the same type of install (system or per user). + DeleteUninstallShortcutsForMSI(is_system_install); } return true; diff --git a/chrome/installer/setup/uninstall.cc b/chrome/installer/setup/uninstall.cc index fe3754b..7b6150c 100644 --- a/chrome/installer/setup/uninstall.cc +++ b/chrome/installer/setup/uninstall.cc @@ -274,33 +274,6 @@ DeleteResult DeleteFilesAndFolders(const std::wstring& exe_path, return result; } -// This method tries to delete a registry key and logs an error message -// in case of failure. It returns true if deletion is successful, -// otherwise false. -bool DeleteRegistryKey(RegKey& key, const std::wstring& key_path) { - LOG(INFO) << "Deleting registry key " << key_path; - if (!key.DeleteKey(key_path.c_str()) && - ::GetLastError() != ERROR_MOD_NOT_FOUND) { - LOG(ERROR) << "Failed to delete registry key: " << key_path; - return false; - } - return true; -} - -// This method tries to delete a registry value and logs an error message -// in case of failure. It returns true if deletion is successful, -// otherwise false. -bool DeleteRegistryValue(HKEY reg_root, const std::wstring& key_path, - const std::wstring& value_name) { - RegKey key(reg_root, key_path.c_str(), KEY_ALL_ACCESS); - LOG(INFO) << "Deleting registry value " << value_name; - if (key.ValueExists(value_name.c_str()) && - !key.DeleteValue(value_name.c_str())) { - LOG(ERROR) << "Failed to delete registry value: " << value_name; - return false; - } - return true; -} // This method checks if Chrome is currently running or if the user has // cancelled the uninstall operation by clicking Cancel on the confirmation @@ -376,36 +349,36 @@ bool installer_setup::DeleteChromeRegistrationKeys(HKEY root, std::wstring html_prog_id(ShellUtil::kRegClasses); file_util::AppendToPath(&html_prog_id, ShellUtil::kChromeHTMLProgId); html_prog_id.append(browser_entry_suffix); - DeleteRegistryKey(key, html_prog_id); + InstallUtil::DeleteRegistryKey(key, html_prog_id); // Delete Software\Clients\StartMenuInternet\Chromium BrowserDistribution* dist = BrowserDistribution::GetDistribution(); std::wstring set_access_key(ShellUtil::kRegStartMenuInternet); file_util::AppendToPath(&set_access_key, dist->GetApplicationName()); set_access_key.append(browser_entry_suffix); - DeleteRegistryKey(key, set_access_key); + InstallUtil::DeleteRegistryKey(key, set_access_key); // We have renamed the StartMenuInternet\chrome.exe to // StartMenuInternet\Chromium so for old users we still need to delete // the old key. std::wstring old_set_access_key(ShellUtil::kRegStartMenuInternet); file_util::AppendToPath(&old_set_access_key, installer_util::kChromeExe); - DeleteRegistryKey(key, old_set_access_key); + InstallUtil::DeleteRegistryKey(key, old_set_access_key); // Delete Software\RegisteredApplications\Chromium - DeleteRegistryValue(root, ShellUtil::kRegRegisteredApplications, - dist->GetApplicationName() + browser_entry_suffix); + InstallUtil::DeleteRegistryValue(root, ShellUtil::kRegRegisteredApplications, + dist->GetApplicationName() + browser_entry_suffix); // Delete Software\Classes\Applications\chrome.exe std::wstring app_key(ShellUtil::kRegClasses); file_util::AppendToPath(&app_key, L"Applications"); file_util::AppendToPath(&app_key, installer_util::kChromeExe); - DeleteRegistryKey(key, app_key); + InstallUtil::DeleteRegistryKey(key, app_key); // Delete the App Paths key that lets explorer find Chrome. std::wstring app_path_key(ShellUtil::kAppPathsRegistryKey); file_util::AppendToPath(&app_path_key, installer_util::kChromeExe); - DeleteRegistryKey(key, app_path_key); + InstallUtil::DeleteRegistryKey(key, app_path_key); // Cleanup OpenWithList for (int i = 0; ShellUtil::kFileAssociations[i] != NULL; i++) { @@ -413,7 +386,7 @@ bool installer_setup::DeleteChromeRegistrationKeys(HKEY root, file_util::AppendToPath(&open_with_key, ShellUtil::kFileAssociations[i]); file_util::AppendToPath(&open_with_key, L"OpenWithList"); file_util::AppendToPath(&open_with_key, installer_util::kChromeExe); - DeleteRegistryKey(key, open_with_key); + InstallUtil::DeleteRegistryKey(key, open_with_key); } key.Close(); @@ -445,13 +418,13 @@ const wchar_t kChromeExtProgId[] = L"ChromiumExt"; std::wstring ext_prog_id(ShellUtil::kRegClasses); file_util::AppendToPath(&ext_prog_id, kChromeExtProgId); ext_prog_id.append(suffix); - DeleteRegistryKey(key, ext_prog_id); + InstallUtil::DeleteRegistryKey(key, ext_prog_id); // Delete Software\Classes\.crx, std::wstring ext_association(ShellUtil::kRegClasses); ext_association.append(L"\\."); ext_association.append(chrome::kExtensionFileExtension); - DeleteRegistryKey(key, ext_association); + InstallUtil::DeleteRegistryKey(key, ext_association); } } @@ -524,8 +497,14 @@ installer_util::InstallStatus installer_setup::UninstallChrome( std::wstring distribution_data(dist->GetDistributionData(&key)); // Remove Control Panel uninstall link and Omaha product key. - DeleteRegistryKey(key, dist->GetUninstallRegPath()); - DeleteRegistryKey(key, dist->GetVersionKey()); + InstallUtil::DeleteRegistryKey(key, dist->GetUninstallRegPath()); + InstallUtil::DeleteRegistryKey(key, dist->GetVersionKey()); + + // Also try to delete the MSI value in the ClientState key (it might not be + // there). This is due to a Google Update behaviour where an uninstall and a + // rapid reinstall might result in stale values from the old ClientState key + // being picked up on reinstall. + InstallUtil::SetMSIMarker(system_uninstall, false); // Remove all Chrome registration keys. installer_util::InstallStatus ret = installer_util::UNKNOWN_STATUS; @@ -548,7 +527,7 @@ installer_util::InstallStatus installer_setup::UninstallChrome( RegKey hklm_key(HKEY_LOCAL_MACHINE, L"", KEY_ALL_ACCESS); std::wstring reg_path(installer::kMediaPlayerRegPath); file_util::AppendToPath(®_path, installer_util::kChromeExe); - DeleteRegistryKey(hklm_key, reg_path); + InstallUtil::DeleteRegistryKey(hklm_key, reg_path); hklm_key.Close(); } |