Skip to content

Commit

Permalink
Fix some problems with machine level install.
Browse files Browse the repository at this point in the history
BUG=2380

Review URL: http://codereview.chromium.org/6402

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@3015 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
kuchhal@chromium.org committed Oct 8, 2008
1 parent 1160976 commit f96ba6c
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 48 deletions.
4 changes: 4 additions & 0 deletions base/file_util.h
Expand Up @@ -208,6 +208,10 @@ bool UpdateShortcutLink(const wchar_t *source, const wchar_t *destination,
const wchar_t *working_dir, const wchar_t *arguments,
const wchar_t *description, const wchar_t *icon,
int icon_index);

// Return true if the given directory is empty
bool IsDirectoryEmpty(const std::wstring& dir_path);

#endif


Expand Down
7 changes: 7 additions & 0 deletions base/file_util_win.cc
Expand Up @@ -365,6 +365,13 @@ bool UpdateShortcutLink(const wchar_t *source, const wchar_t *destination,
return SUCCEEDED(result);
}

bool IsDirectoryEmpty(const std::wstring& dir_path) {
FileEnumerator files(dir_path, false, FileEnumerator::FILES_AND_DIRECTORIES);
if (files.Next().empty())
return true;
return false;
}

bool GetTempDir(std::wstring* path) {
wchar_t temp_path[MAX_PATH + 1];
DWORD path_len = ::GetTempPath(MAX_PATH, temp_path);
Expand Down
4 changes: 4 additions & 0 deletions chrome/installer/setup/install.cc
Expand Up @@ -50,6 +50,10 @@ void AddUninstallShortcutWorkItems(HKEY reg_root,
file_util::GetFilenameFromPath(exe_path));
uninstall_cmd.append(L"\" --");
uninstall_cmd.append(installer_util::switches::kUninstall);
if (reg_root == HKEY_LOCAL_MACHINE) {
uninstall_cmd.append(L" --");
uninstall_cmd.append(installer_util::switches::kSystemInstall);
}

// Create DisplayName, UninstallString and InstallLocation keys
BrowserDistribution* dist = BrowserDistribution::GetDistribution();
Expand Down
2 changes: 1 addition & 1 deletion chrome/installer/setup/main.cc
Expand Up @@ -272,7 +272,7 @@ installer_util::InstallStatus InstallChrome(const CommandLine& cmd_line,

BrowserDistribution* dist = BrowserDistribution::GetDistribution();
dist->UpdateDiffInstallStatus(system_install, incremental_install,
install_status);
install_status);
return install_status;
}

Expand Down
5 changes: 5 additions & 0 deletions chrome/installer/setup/setup.cc
Expand Up @@ -130,6 +130,11 @@ bool CreateOrUpdateChromeShortcuts(const std::wstring& exe_path,
file_util::GetFilenameFromPath(exe_path));
std::wstring arguments(L" --");
arguments.append(installer_util::switches::kUninstall);
if (system_install) {
arguments.append(L" --");
arguments.append(installer_util::switches::kSystemInstall);
}

LOG(INFO) << "Creating/updating uninstall link at " << uninstall_link;
std::wstring target_folder = file_util::GetDirectoryFromPath(install_path);
ret2 = file_util::CreateShortcutLink(setup_exe.c_str(),
Expand Down
66 changes: 45 additions & 21 deletions chrome/installer/setup/uninstall.cc
Expand Up @@ -57,6 +57,49 @@ void DeleteChromeShortcut(bool system_uninstall) {
}
}

// Deletes all installed files of Chromium and Folders. Before deleting it
// needs to move setup.exe in a temp folder because the current process
// is using that file. It returns false when it can not get the path to
// installation folder, in all other cases it returns true even in case
// of error (only logs the error).
bool DeleteFilesAndFolders(const std::wstring& exe_path, bool system_uninstall,
const installer::Version& installed_version) {
std::wstring install_path(installer::GetChromeInstallPath(system_uninstall));
if (install_path.empty()) {
LOG(ERROR) << "Could not get installation destination path.";
return false; // Nothing else we can do for uninstall, so we return.
} else {
LOG(INFO) << "install destination path: " << install_path;
}

std::wstring setup_exe(installer::GetInstallerPathUnderChrome(
install_path, installed_version.GetString()));
file_util::AppendToPath(&setup_exe, file_util::GetFilenameFromPath(exe_path));

std::wstring temp_file;
file_util::CreateTemporaryFileName(&temp_file);
file_util::Move(setup_exe, temp_file);

LOG(INFO) << "Deleting install path " << install_path;
if (!file_util::Delete(install_path, true))
LOG(ERROR) << "Failed to delete folder: " << install_path;

// Now check and delete if the parent directories are empty
// For example Google\Chrome or Chromium
std::wstring parent_dir = file_util::GetDirectoryFromPath(install_path);
if (!parent_dir.empty() && file_util::IsDirectoryEmpty(parent_dir)) {
if (!file_util::Delete(parent_dir, true))
LOG(ERROR) << "Failed to delete folder: " << parent_dir;
parent_dir = file_util::GetDirectoryFromPath(parent_dir);
if (!parent_dir.empty() &&
file_util::IsDirectoryEmpty(parent_dir)) {
if (!file_util::Delete(parent_dir, true))
LOG(ERROR) << "Failed to delete folder: " << parent_dir;
}
}
return true;
}

// 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.
Expand Down Expand Up @@ -126,8 +169,6 @@ installer_util::InstallStatus installer_setup::UninstallChrome(
if (status != installer_util::UNINSTALL_CONFIRMED)
return status;

BrowserDistribution* dist = BrowserDistribution::GetDistribution();
dist->DoPreUninstallOperations();
#if defined(GOOGLE_CHROME_BUILD)
// TODO(rahulk): This should be done by DoPreUninstallOperations call above
wchar_t product[39]; // GUID + '\0'
Expand All @@ -151,6 +192,7 @@ installer_util::InstallStatus installer_setup::UninstallChrome(
// Delete the registry keys (Uninstall key and Version key).
HKEY reg_root = system_uninstall ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
RegKey key(reg_root, L"", KEY_ALL_ACCESS);
BrowserDistribution* dist = BrowserDistribution::GetDistribution();
DeleteRegistryKey(key, dist->GetUninstallRegPath());
DeleteRegistryKey(key, dist->GetVersionKey());

Expand Down Expand Up @@ -188,26 +230,8 @@ installer_util::InstallStatus installer_setup::UninstallChrome(

// Finally delete all the files from Chrome folder after moving setup.exe
// to a temp location.
std::wstring install_path(installer::GetChromeInstallPath(system_uninstall));
if (install_path.empty()) {
LOG(ERROR) << "Could not get installation destination path.";
// Nothing else we could do for uninstall, so we return.
if (!DeleteFilesAndFolders(exe_path, system_uninstall, installed_version))
return installer_util::UNINSTALL_FAILED;
} else {
LOG(INFO) << "install destination path: " << install_path;
}

std::wstring setup_exe(installer::GetInstallerPathUnderChrome(
install_path, installed_version.GetString()));
file_util::AppendToPath(&setup_exe, file_util::GetFilenameFromPath(exe_path));

std::wstring temp_file;
file_util::CreateTemporaryFileName(&temp_file);
file_util::Move(setup_exe, temp_file);

LOG(INFO) << "Deleting install path " << install_path;
if (!file_util::Delete(install_path, true))
LOG(ERROR) << "Failed to delete folder: " << install_path;

LOG(INFO) << "Uninstallation complete. Launching Uninstall survey.";
dist->DoPostUninstallOperations(installed_version);
Expand Down
3 changes: 0 additions & 3 deletions chrome/installer/util/browser_distribution.cc
Expand Up @@ -26,9 +26,6 @@ void BrowserDistribution::DoPostUninstallOperations(
const installer::Version& version) {
}

void BrowserDistribution::DoPreUninstallOperations() {
}

std::wstring BrowserDistribution::GetApplicationName() {
return L"Chromium";
}
Expand Down
2 changes: 0 additions & 2 deletions chrome/installer/util/browser_distribution.h
Expand Up @@ -19,8 +19,6 @@ class BrowserDistribution {

virtual void DoPostUninstallOperations(const installer::Version& version);

virtual void DoPreUninstallOperations();

virtual std::wstring GetApplicationName();

virtual std::wstring GetInstallSubDir();
Expand Down
19 changes: 0 additions & 19 deletions chrome/installer/util/google_chrome_distribution.cc
Expand Up @@ -73,25 +73,6 @@ void GoogleChromeDistribution::DoPostUninstallOperations(
WMIProcessUtil::Launch(command, &pid);
}

// Uninstall Chrome specific Gears. First we find Gears MSI ProductId (that
// changes with every new version of Gears) using Gears MSI UpgradeCode (that
// does not change) and then uninstall Gears using API.
void GoogleChromeDistribution::DoPreUninstallOperations() {
/* TODO(rahulk) this comment is commented for now because it is causing extra
dependencies for the renderer. Need to remove ifdef from uninstall.cc and
uncomment this function.
wchar_t product[39]; // GUID + '\0'
MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); // Don't show any UI to user.
for (int i = 0; MsiEnumRelatedProducts(google_update::kGearsUpgradeCode, 0, i,
product) != ERROR_NO_MORE_ITEMS; ++i) {
LOG(INFO) << "Uninstalling Gears - " << product;
unsigned int ret = MsiConfigureProduct(product, INSTALLLEVEL_MAXIMUM,
INSTALLSTATE_ABSENT);
if (ret != ERROR_SUCCESS)
LOG(ERROR) << "Failed to uninstall Gears " << product << ": " << ret;
}*/
}

std::wstring GoogleChromeDistribution::GetApplicationName() {
const std::wstring& product_name =
installer_util::GetLocalizedString(IDS_PRODUCT_NAME_BASE);
Expand Down
2 changes: 0 additions & 2 deletions chrome/installer/util/google_chrome_distribution.h
Expand Up @@ -15,8 +15,6 @@ class GoogleChromeDistribution : public BrowserDistribution {
public:
virtual void DoPostUninstallOperations(const installer::Version& version);

virtual void DoPreUninstallOperations();

virtual std::wstring GetApplicationName();

virtual std::wstring GetInstallSubDir();
Expand Down

0 comments on commit f96ba6c

Please sign in to comment.