summaryrefslogtreecommitdiffstats
path: root/chrome/installer/setup
diff options
context:
space:
mode:
authorrobertshield@chromium.org <robertshield@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-07 17:27:46 +0000
committerrobertshield@chromium.org <robertshield@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-07 17:27:46 +0000
commitcdc038860e32bfeff7e8e8839deaa1f1185a1373 (patch)
tree496bedf827fc608688267540f3b9715449605629 /chrome/installer/setup
parent8784578d7e13d112fd205d3ee4fc1fe0018beea0 (diff)
downloadchromium_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.cc43
-rw-r--r--chrome/installer/setup/uninstall.cc59
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(&reg_path, installer_util::kChromeExe);
- DeleteRegistryKey(hklm_key, reg_path);
+ InstallUtil::DeleteRegistryKey(hklm_key, reg_path);
hklm_key.Close();
}