Commit 6d2bd3fc authored by gab@chromium.org's avatar gab@chromium.org

[Fixit-Dec-2012] Auto-launch system-level Chrome post user-level Chrome self-destruction.

Also changed self-destruct to launch setup.exe using ShellExecute instead of base::LaunchProcess to allow us to specify SEE_MASK_FLAG_LOG_USAGE to flip to the desktop as documented in "DevelopinganewexperienceDesktopBrowser". This only seems to work when ShellExecute is called from an immersive process and thus setup.exe must be launched with this flag (if it's not and setup later tries to ShellExecute the system-level Chrome with that flag, the desktop flip doesn't occur...).

Also fixed InstallUtil::GetSentinelFilePath() which used to get DIR_EXE from the PathService to determine whether it was a user-level install and if so return DIR_EXE as the sentinel file path; this was wrong when called from setup.exe as DIR_EXE is not Application\ in that case, it's Application\<version>\Installer...! Thankfully this method was not used to set the sentinel (so that we don't have to keep checking for sentinel files in the wrong places); we could up until this CL however get constant false negatives when looking for sentinels with this method.

This CL depends on https://codereview.chromium.org/11636031/.

BUG=165048
TEST=Self-destruct with/without First Run having occured (prior to the system-level install) for the user-level Chrome; the self-destruct should occur and launch System-level Chrome with/without the First Run flow (i.e. with First Run only if the self-destructing Chrome itself hadn't undergone First Run already).
On Win8, the above scenarios should work whether the user-level Chrome prefers Metro or not (if it does prefer Metro the immersive launch should flip back to the desktop for the self-destruct -- the self-destruct message dialog is still suppressed in that case however).

Review URL: https://chromiumcodereview.appspot.com/11685006

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@175249 0039d316-1c4b-4281-b951-d872f2087c98
parent 6add02aa
......@@ -355,13 +355,26 @@ bool ChromeBrowserMainPartsWin::CheckMachineLevelInstall() {
CommandLine uninstall_cmd(
InstallUtil::GetChromeUninstallCmd(false, dist->GetType()));
if (!uninstall_cmd.GetProgram().empty()) {
uninstall_cmd.AppendSwitch(installer::switches::kSelfDestruct);
uninstall_cmd.AppendSwitch(installer::switches::kForceUninstall);
uninstall_cmd.AppendSwitch(
installer::switches::kDoNotRemoveSharedItems);
base::LaunchOptions launch_options;
const FilePath setup_exe(uninstall_cmd.GetProgram());
const string16 params(uninstall_cmd.GetArgumentsString());
SHELLEXECUTEINFO sei = { sizeof(sei) };
sei.fMask = SEE_MASK_NOASYNC;
sei.nShow = SW_SHOWNORMAL;
sei.lpFile = setup_exe.value().c_str();
sei.lpParameters = params.c_str();
// On Windows 8 SEE_MASK_FLAG_LOG_USAGE is necessary to guarantee we
// flip to the Desktop when launching.
if (is_metro)
launch_options.force_breakaway_from_job_ = true;
base::LaunchProcess(uninstall_cmd, launch_options, NULL);
sei.fMask |= SEE_MASK_FLAG_LOG_USAGE;
if (!::ShellExecuteEx(&sei))
DPCHECK(false);
}
return true;
}
......
......@@ -28,6 +28,7 @@
#include "base/win/win_util.h"
#include "base/win/windows_version.h"
#include "breakpad/src/client/windows/handler/exception_handler.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/installer/setup/chrome_frame_quick_enable.h"
#include "chrome/installer/setup/chrome_frame_ready_mode.h"
......@@ -1004,12 +1005,43 @@ installer::InstallStatus UninstallProducts(
const CommandLine& cmd_line) {
const Products& products = installer_state.products();
if (installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER)) {
// Decide whether Active Setup should be triggered and/or system-level Chrome
// should be launched post-uninstall. This needs to be done outside the
// UninstallProduct calls as some of them might terminate the processes
// launched by a previous one otherwise...
bool trigger_active_setup = false;
// System-level Chrome will be launched via this command if its program gets
// set below.
CommandLine system_level_cmd(CommandLine::NO_PROGRAM);
const Product* chrome =
installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER);
if (chrome) {
// InstallerState::Initialize always puts Chrome first, and we rely on that
// here for this reason: if Chrome is in-use, the user will be prompted to
// confirm uninstallation. Upon cancel, we should not continue with the
// other products.
DCHECK(products[0]->is_chrome());
if (cmd_line.HasSwitch(installer::switches::kSelfDestruct) &&
!installer_state.system_install()) {
BrowserDistribution* dist = chrome->distribution();
const FilePath system_exe_path(
installer::GetChromeInstallPath(true, dist)
.Append(installer::kChromeExe));
system_level_cmd.SetProgram(system_exe_path);
FilePath first_run_sentinel;
InstallUtil::GetSentinelFilePath(
chrome::kFirstRunSentinel, dist, &first_run_sentinel);
if (file_util::PathExists(first_run_sentinel)) {
// If the Chrome being self-destructed has already undergone First Run,
// trigger Active Setup and make sure the system-level Chrome doesn't go
// through first run.
trigger_active_setup = true;
system_level_cmd.AppendSwitch(::switches::kNoFirstRun);
}
}
}
if (installer_state.FindProduct(BrowserDistribution::CHROME_BINARIES)) {
// Chrome Binaries should be last; if something else is cancelled, they
......@@ -1035,6 +1067,12 @@ installer::InstallStatus UninstallProducts(
installer::CleanUpInstallationDirectoryAfterUninstall(
original_state, installer_state, cmd_line, &install_status);
if (trigger_active_setup)
InstallUtil::TriggerActiveSetupCommand();
if (!system_level_cmd.GetProgram().empty())
base::LaunchProcess(system_level_cmd, base::LaunchOptions(), NULL);
// Tell Google Update that an uninstall has taken place.
// Ignore the return value: success or failure of Google Update
// has no bearing on the success or failure of Chrome's uninstallation.
......
......@@ -1342,14 +1342,6 @@ InstallStatus UninstallProduct(const InstallationState& original_state,
if (!backup_state_file.empty())
file_util::Delete(backup_state_file, false);
// If user-level Chrome is being uninstalled and system-level Chrome is
// present, launch the system-level Active Setup command to do post-install
// tasks for this user (i.e., create shortcuts).
if (product.is_chrome() && !installer_state.system_install() &&
original_state.GetProductState(true, browser_dist->GetType())) {
InstallUtil::TriggerActiveSetupCommand();
}
return ret;
}
......
......@@ -384,7 +384,22 @@ bool InstallUtil::GetSentinelFilePath(const FilePath::CharType* file,
return false;
if (IsPerUserInstall(exe_path.value().c_str())) {
*path = exe_path;
const FilePath maybe_product_dir(exe_path.DirName().DirName());
if (file_util::PathExists(exe_path.Append(installer::kChromeExe))) {
// DIR_EXE is most likely Chrome's directory in which case |exe_path| is
// the user-level sentinel path.
*path = exe_path;
} else if (file_util::PathExists(
maybe_product_dir.Append(installer::kChromeExe))) {
// DIR_EXE can also be the Installer directory if this is called from a
// setup.exe running from Application\<version>\Installer (see
// InstallerState::GetInstallerDirectory) in which case Chrome's directory
// is two levels up.
*path = maybe_product_dir;
} else {
NOTREACHED();
return false;
}
} else {
std::vector<FilePath> user_data_dir_paths;
installer::GetChromeUserDataPaths(dist, &user_data_dir_paths);
......
......@@ -154,6 +154,10 @@ const char kRemoveChromeRegistration[] = "remove-chrome-registration";
// line flag so that we try the launch only once.
const char kRunAsAdmin[] = "run-as-admin";
// Combined with --uninstall, signals to setup.exe that this uninstall was
// triggered by a self-destructing Chrome.
const char kSelfDestruct[] = "self-destruct";
// Install Chrome to system wise location. The default is per user install.
const char kSystemLevel[] = "system-level";
......
......@@ -165,6 +165,7 @@ extern const char kRegisterURLProtocol[];
extern const char kRenameChromeExe[];
extern const char kRemoveChromeRegistration[];
extern const char kRunAsAdmin[];
extern const char kSelfDestruct[];
extern const char kSystemLevel[];
extern const char kUninstall[];
extern const char kUpdateSetupExe[];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment