| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 // | 4 // |
| 5 // This file contains the definitions of the installer functions that build | 5 // This file contains the definitions of the installer functions that build |
| 6 // the WorkItemList used to install the application. | 6 // the WorkItemList used to install the application. |
| 7 | 7 |
| 8 #include "chrome/installer/setup/install_worker.h" | 8 #include "chrome/installer/setup/install_worker.h" |
| 9 | 9 |
| 10 #include <oaidl.h> | 10 #include <oaidl.h> |
| 11 #include <shlobj.h> | 11 #include <shlobj.h> |
| 12 #include <time.h> | 12 #include <time.h> |
| 13 | 13 |
| 14 #include <vector> | 14 #include <vector> |
| 15 | 15 |
| 16 #include "base/command_line.h" | 16 #include "base/command_line.h" |
| 17 #include "base/file_path.h" | 17 #include "base/file_path.h" |
| 18 #include "base/file_util.h" | 18 #include "base/file_util.h" |
| 19 #include "base/logging.h" | 19 #include "base/logging.h" |
| 20 #include "base/path_service.h" | 20 #include "base/path_service.h" |
| 21 #include "base/string_util.h" | 21 #include "base/string_util.h" |
| 22 #include "base/utf_string_conversions.h" | 22 #include "base/utf_string_conversions.h" |
| 23 #include "base/version.h" | 23 #include "base/version.h" |
| 24 #include "base/win/registry.h" | 24 #include "base/win/registry.h" |
| 25 #include "base/win/windows_version.h" | 25 #include "base/win/windows_version.h" |
| 26 #include "chrome/common/chrome_constants.h" | 26 #include "chrome/common/chrome_constants.h" |
| 27 #include "chrome/common/chrome_switches.h" |
| 27 #include "chrome/installer/setup/install.h" | 28 #include "chrome/installer/setup/install.h" |
| 28 #include "chrome/installer/setup/setup_constants.h" | 29 #include "chrome/installer/setup/setup_constants.h" |
| 29 #include "chrome/installer/util/conditional_work_item_list.h" | 30 #include "chrome/installer/util/conditional_work_item_list.h" |
| 30 #include "chrome/installer/util/create_reg_key_work_item.h" | 31 #include "chrome/installer/util/create_reg_key_work_item.h" |
| 31 #include "chrome/installer/util/google_update_constants.h" | 32 #include "chrome/installer/util/google_update_constants.h" |
| 32 #include "chrome/installer/util/helper.h" | 33 #include "chrome/installer/util/helper.h" |
| 33 #include "chrome/installer/util/installation_state.h" | 34 #include "chrome/installer/util/installation_state.h" |
| 34 #include "chrome/installer/util/installer_state.h" | 35 #include "chrome/installer/util/installer_state.h" |
| 35 #include "chrome/installer/util/install_util.h" | 36 #include "chrome/installer/util/install_util.h" |
| 36 #include "chrome/installer/util/l10n_string_util.h" | 37 #include "chrome/installer/util/l10n_string_util.h" |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 const FilePath& temp_path, | 94 const FilePath& temp_path, |
| 94 const Version& new_version, | 95 const Version& new_version, |
| 95 WorkItemList* install_list) { | 96 WorkItemList* install_list) { |
| 96 DCHECK(install_list); | 97 DCHECK(install_list); |
| 97 FilePath installer_dir(installer_state.GetInstallerDirectory(new_version)); | 98 FilePath installer_dir(installer_state.GetInstallerDirectory(new_version)); |
| 98 install_list->AddCreateDirWorkItem(installer_dir); | 99 install_list->AddCreateDirWorkItem(installer_dir); |
| 99 | 100 |
| 100 FilePath exe_dst(installer_dir.Append(setup_path.BaseName())); | 101 FilePath exe_dst(installer_dir.Append(setup_path.BaseName())); |
| 101 FilePath archive_dst(installer_dir.Append(archive_path.BaseName())); | 102 FilePath archive_dst(installer_dir.Append(archive_path.BaseName())); |
| 102 | 103 |
| 103 install_list->AddCopyTreeWorkItem(setup_path.value(), exe_dst.value(), | 104 if (exe_dst != setup_path) { |
| 104 temp_path.value(), WorkItem::ALWAYS); | 105 install_list->AddCopyTreeWorkItem(setup_path.value(), exe_dst.value(), |
| 106 temp_path.value(), WorkItem::ALWAYS); |
| 107 } |
| 105 | 108 |
| 106 // In the past, we copied rather than moved for system level installs so that | 109 if (archive_path != archive_dst) { |
| 107 // the permissions of %ProgramFiles% would be picked up. Now that |temp_path| | 110 // In the past, we copied rather than moved for system level installs so |
| 108 // is in %ProgramFiles% for system level installs (and in %LOCALAPPDATA% | 111 // that the permissions of %ProgramFiles% would be picked up. Now that |
| 109 // otherwise), there is no need to do this for the archive. Setup.exe, on | 112 // |temp_path| is in %ProgramFiles% for system level installs (and in |
| 110 // the other hand, is created elsewhere so it must always be copied. | 113 // %LOCALAPPDATA% otherwise), there is no need to do this for the archive. |
| 111 install_list->AddMoveTreeWorkItem(archive_path.value(), archive_dst.value(), | 114 // Setup.exe, on the other hand, is created elsewhere so it must always be |
| 112 temp_path.value(), WorkItem::ALWAYS_MOVE); | 115 // copied. |
| 116 install_list->AddMoveTreeWorkItem(archive_path.value(), archive_dst.value(), |
| 117 temp_path.value(), WorkItem::ALWAYS_MOVE); |
| 118 } |
| 113 } | 119 } |
| 114 | 120 |
| 115 // This method adds work items to create (or update) Chrome uninstall entry in | 121 // This method adds work items to create (or update) Chrome uninstall entry in |
| 116 // either the Control Panel->Add/Remove Programs list or in the Omaha client | 122 // either the Control Panel->Add/Remove Programs list or in the Omaha client |
| 117 // state key if running under an MSI installer. | 123 // state key if running under an MSI installer. |
| 118 void AddUninstallShortcutWorkItems(const InstallerState& installer_state, | 124 void AddUninstallShortcutWorkItems(const InstallerState& installer_state, |
| 119 const FilePath& setup_path, | 125 const FilePath& setup_path, |
| 120 const Version& new_version, | 126 const Version& new_version, |
| 121 WorkItemList* install_list, | 127 WorkItemList* install_list, |
| 122 const Product& product) { | 128 const Product& product) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 133 // locate the setup.exe instance used for binary patching. | 139 // locate the setup.exe instance used for binary patching. |
| 134 // Do not quote the command line for the MSI invocation. | 140 // Do not quote the command line for the MSI invocation. |
| 135 FilePath install_path(installer_state.target_path()); | 141 FilePath install_path(installer_state.target_path()); |
| 136 FilePath installer_path(installer_state.GetInstallerDirectory(new_version)); | 142 FilePath installer_path(installer_state.GetInstallerDirectory(new_version)); |
| 137 installer_path = installer_path.Append(setup_path.BaseName()); | 143 installer_path = installer_path.Append(setup_path.BaseName()); |
| 138 | 144 |
| 139 CommandLine uninstall_arguments(CommandLine::NO_PROGRAM); | 145 CommandLine uninstall_arguments(CommandLine::NO_PROGRAM); |
| 140 AppendUninstallCommandLineFlags(installer_state, product, | 146 AppendUninstallCommandLineFlags(installer_state, product, |
| 141 &uninstall_arguments); | 147 &uninstall_arguments); |
| 142 | 148 |
| 143 // The Chrome uninstallation command serves as the master uninstall command | 149 // If Chrome Frame is installed in Ready Mode, add --chrome-frame to Chrome's |
| 144 // for Chrome + all other products (i.e. Chrome Frame) that do not have an | 150 // uninstall entry. We skip this processing in case of uninstall since this |
| 145 // uninstall entry in the Add/Remove Programs dialog. We skip this processing | 151 // means that Chrome Frame is being uninstalled, so there's no need to do any |
| 146 // in case of uninstall since this means that Chrome Frame is being | 152 // looping. |
| 147 // uninstalled, so there's no need to do any looping. | |
| 148 if (product.is_chrome() && | 153 if (product.is_chrome() && |
| 149 installer_state.operation() != InstallerState::UNINSTALL) { | 154 installer_state.operation() != InstallerState::UNINSTALL) { |
| 150 const Products& products = installer_state.products(); | 155 const Product* chrome_frame = |
| 151 for (size_t i = 0; i < products.size(); ++i) { | 156 installer_state.FindProduct(BrowserDistribution::CHROME_FRAME); |
| 152 const Product& p = *products[i]; | 157 if (chrome_frame && chrome_frame->HasOption(kOptionReadyMode)) |
| 153 if (!p.is_chrome() && !p.ShouldCreateUninstallEntry()) | 158 chrome_frame->AppendProductFlags(&uninstall_arguments); |
| 154 p.AppendProductFlags(&uninstall_arguments); | |
| 155 } | |
| 156 } | 159 } |
| 157 | 160 |
| 158 std::wstring update_state_key(browser_dist->GetStateKey()); | 161 std::wstring update_state_key(browser_dist->GetStateKey()); |
| 159 install_list->AddCreateRegKeyWorkItem(reg_root, update_state_key); | 162 install_list->AddCreateRegKeyWorkItem(reg_root, update_state_key); |
| 160 install_list->AddSetRegValueWorkItem(reg_root, update_state_key, | 163 install_list->AddSetRegValueWorkItem(reg_root, update_state_key, |
| 161 installer::kUninstallStringField, installer_path.value(), true); | 164 installer::kUninstallStringField, installer_path.value(), true); |
| 162 install_list->AddSetRegValueWorkItem(reg_root, update_state_key, | 165 install_list->AddSetRegValueWorkItem(reg_root, update_state_key, |
| 163 installer::kUninstallArgumentsField, | 166 installer::kUninstallArgumentsField, |
| 164 uninstall_arguments.GetCommandLineString(), true); | 167 uninstall_arguments.GetCommandLineString(), true); |
| 165 | 168 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 if (version_components.size() == 4) { | 221 if (version_components.size() == 4) { |
| 219 // Our version should be in major.minor.build.rev. | 222 // Our version should be in major.minor.build.rev. |
| 220 install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, | 223 install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, |
| 221 L"VersionMajor", static_cast<DWORD>(version_components[2]), true); | 224 L"VersionMajor", static_cast<DWORD>(version_components[2]), true); |
| 222 install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, | 225 install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, |
| 223 L"VersionMinor", static_cast<DWORD>(version_components[3]), true); | 226 L"VersionMinor", static_cast<DWORD>(version_components[3]), true); |
| 224 } | 227 } |
| 225 } | 228 } |
| 226 } | 229 } |
| 227 | 230 |
| 228 // Add uninstall-related work items for multi-install scenarios. | |
| 229 void AddMultiUninstallWorkItems(const InstallerState& installer_state, | |
| 230 const FilePath& setup_path, | |
| 231 const Version& new_version, | |
| 232 WorkItemList* install_list) { | |
| 233 DCHECK(installer_state.is_multi_install()); | |
| 234 | |
| 235 // The mini_installer needs a reliable way to locate setup.exe for diff | |
| 236 // updates. For single-installs, the product's ClientState key is consulted | |
| 237 // (Chrome's or Chrome Frame's). For multi-installs, the binaries' key is | |
| 238 // used. | |
| 239 const HKEY reg_root = installer_state.root_key(); | |
| 240 std::wstring binaries_state_key( | |
| 241 installer_state.multi_package_binaries_distribution()->GetStateKey()); | |
| 242 FilePath installer_path( | |
| 243 installer_state.GetInstallerDirectory(new_version) | |
| 244 .Append(setup_path.BaseName())); | |
| 245 install_list->AddCreateRegKeyWorkItem(reg_root, binaries_state_key); | |
| 246 install_list->AddSetRegValueWorkItem(reg_root, binaries_state_key, | |
| 247 installer::kUninstallStringField, installer_path.value(), true); | |
| 248 } | |
| 249 | |
| 250 // Create Version key for a product (if not already present) and sets the new | 231 // Create Version key for a product (if not already present) and sets the new |
| 251 // product version as the last step. | 232 // product version as the last step. |
| 252 void AddVersionKeyWorkItems(HKEY root, | 233 void AddVersionKeyWorkItems(HKEY root, |
| 253 BrowserDistribution* dist, | 234 BrowserDistribution* dist, |
| 254 const Version& new_version, | 235 const Version& new_version, |
| 255 bool add_language_identifier, | 236 bool add_language_identifier, |
| 256 WorkItemList* list) { | 237 WorkItemList* list) { |
| 257 // Create Version key for each distribution (if not already present) and set | 238 // Create Version key for each distribution (if not already present) and set |
| 258 // the new product version as the last step. | 239 // the new product version as the last step. |
| 259 std::wstring version_key(dist->GetVersionKey()); | 240 std::wstring version_key(dist->GetVersionKey()); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 276 list->AddSetRegValueWorkItem(root, version_key, | 257 list->AddSetRegValueWorkItem(root, version_key, |
| 277 google_update::kRegLangField, language, | 258 google_update::kRegLangField, language, |
| 278 false); // do not overwrite language | 259 false); // do not overwrite language |
| 279 } | 260 } |
| 280 list->AddSetRegValueWorkItem(root, version_key, | 261 list->AddSetRegValueWorkItem(root, version_key, |
| 281 google_update::kRegVersionField, | 262 google_update::kRegVersionField, |
| 282 ASCIIToWide(new_version.GetString()), | 263 ASCIIToWide(new_version.GetString()), |
| 283 true); // overwrite version | 264 true); // overwrite version |
| 284 } | 265 } |
| 285 | 266 |
| 267 void AddInstallAppCommandWorkItems(const InstallerState& installer_state, |
| 268 const InstallationState& machine_state, |
| 269 const FilePath* setup_path, |
| 270 const Version* new_version, |
| 271 const Product& product, |
| 272 WorkItemList* work_item_list) { |
| 273 DCHECK(product.is_chrome_app_host()); |
| 274 |
| 275 std::wstring cmd_key(product.distribution()->GetVersionKey()); |
| 276 cmd_key.append(1, L'\\').append(google_update::kRegCommandsKey) |
| 277 .append(1, L'\\').append(kCmdInstallApp); |
| 278 |
| 279 if (installer_state.operation() != InstallerState::UNINSTALL) { |
| 280 FilePath target_path(installer_state.target_path()); |
| 281 CommandLine cmd_line(target_path.Append(installer::kChromeAppHostExe)); |
| 282 cmd_line.AppendSwitchASCII(::switches::kAppsInstallFromManifestURL, "%1"); |
| 283 |
| 284 AppCommand cmd(cmd_line.GetCommandLineString(), true, true); |
| 285 cmd.AddWorkItems(installer_state.root_key(), cmd_key, work_item_list); |
| 286 } else { |
| 287 work_item_list->AddDeleteRegKeyWorkItem(installer_state.root_key(), |
| 288 cmd_key)->set_log_message( |
| 289 "removing install-application command"); |
| 290 } |
| 291 } |
| 292 |
| 286 void AddProductSpecificWorkItems(const InstallationState& original_state, | 293 void AddProductSpecificWorkItems(const InstallationState& original_state, |
| 287 const InstallerState& installer_state, | 294 const InstallerState& installer_state, |
| 288 const FilePath& setup_path, | 295 const FilePath& setup_path, |
| 289 const Version& new_version, | 296 const Version& new_version, |
| 290 WorkItemList* list) { | 297 WorkItemList* list) { |
| 291 const Products& products = installer_state.products(); | 298 const Products& products = installer_state.products(); |
| 292 for (size_t i = 0; i < products.size(); ++i) { | 299 for (size_t i = 0; i < products.size(); ++i) { |
| 293 const Product& p = *products[i]; | 300 const Product& p = *products[i]; |
| 294 if (p.is_chrome_frame()) { | 301 if (p.is_chrome_frame()) { |
| 295 AddChromeFrameWorkItems(original_state, installer_state, setup_path, | 302 AddChromeFrameWorkItems(original_state, installer_state, setup_path, |
| 296 new_version, p, list); | 303 new_version, p, list); |
| 297 } | 304 } |
| 305 if (p.is_chrome_app_host()) { |
| 306 AddInstallAppCommandWorkItems(installer_state, original_state, |
| 307 &setup_path, &new_version, p, list); |
| 308 } |
| 298 } | 309 } |
| 299 } | 310 } |
| 300 | 311 |
| 301 // Mirror oeminstall the first time anything is installed multi. There is no | 312 // Mirror oeminstall the first time anything is installed multi. There is no |
| 302 // need to update the value on future install/update runs since this value never | 313 // need to update the value on future install/update runs since this value never |
| 303 // changes. Note that the value is removed by Google Update after EULA | 314 // changes. Note that the value is removed by Google Update after EULA |
| 304 // acceptance is processed. | 315 // acceptance is processed. |
| 305 void AddOemInstallWorkItems(const InstallationState& original_state, | 316 void AddOemInstallWorkItems(const InstallationState& original_state, |
| 306 const InstallerState& installer_state, | 317 const InstallerState& installer_state, |
| 307 WorkItemList* install_list) { | 318 WorkItemList* install_list) { |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 556 // do a few post install tasks: | 567 // do a few post install tasks: |
| 557 // - Handle the case of in-use-update by updating "opv" (old version) key or | 568 // - Handle the case of in-use-update by updating "opv" (old version) key or |
| 558 // deleting it if not required. | 569 // deleting it if not required. |
| 559 // - Register any new dlls and unregister old dlls. | 570 // - Register any new dlls and unregister old dlls. |
| 560 // - If this is an MSI install, ensures that the MSI marker is set, and sets | 571 // - If this is an MSI install, ensures that the MSI marker is set, and sets |
| 561 // it if not. | 572 // it if not. |
| 562 // If these operations are successful, the function returns true, otherwise | 573 // If these operations are successful, the function returns true, otherwise |
| 563 // false. | 574 // false. |
| 564 bool AppendPostInstallTasks(const InstallerState& installer_state, | 575 bool AppendPostInstallTasks(const InstallerState& installer_state, |
| 565 const FilePath& setup_path, | 576 const FilePath& setup_path, |
| 566 const FilePath& new_chrome_exe, | |
| 567 const Version* current_version, | 577 const Version* current_version, |
| 568 const Version& new_version, | 578 const Version& new_version, |
| 569 const FilePath& temp_path, | 579 const FilePath& temp_path, |
| 570 WorkItemList* post_install_task_list) { | 580 WorkItemList* post_install_task_list) { |
| 571 DCHECK(post_install_task_list); | 581 DCHECK(post_install_task_list); |
| 572 | 582 |
| 573 HKEY root = installer_state.root_key(); | 583 HKEY root = installer_state.root_key(); |
| 574 const Products& products = installer_state.products(); | 584 const Products& products = installer_state.products(); |
| 585 FilePath new_chrome_exe( |
| 586 installer_state.target_path().Append(installer::kChromeNewExe)); |
| 575 | 587 |
| 576 // Append work items that will only be executed if this was an update. | 588 // Append work items that will only be executed if this was an update. |
| 577 // We update the 'opv' value with the current version that is active, | 589 // We update the 'opv' value with the current version that is active, |
| 578 // the 'cpv' value with the critical update version (if present), and the | 590 // the 'cpv' value with the critical update version (if present), and the |
| 579 // 'cmd' value with the rename command to run. | 591 // 'cmd' value with the rename command to run. |
| 580 { | 592 { |
| 581 scoped_ptr<WorkItemList> in_use_update_work_items( | 593 scoped_ptr<WorkItemList> in_use_update_work_items( |
| 582 WorkItem::CreateConditionalWorkItemList( | 594 WorkItem::CreateConditionalWorkItemList( |
| 583 new ConditionRunIfFileExists(new_chrome_exe))); | 595 new ConditionRunIfFileExists(new_chrome_exe))); |
| 584 in_use_update_work_items->set_log_message("InUseUpdateWorkItemList"); | 596 in_use_update_work_items->set_log_message("InUseUpdateWorkItemList"); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 if (installer_state.is_multi_install()) { | 717 if (installer_state.is_multi_install()) { |
| 706 AddSetMsiMarkerWorkItem(installer_state, | 718 AddSetMsiMarkerWorkItem(installer_state, |
| 707 installer_state.multi_package_binaries_distribution(), true, | 719 installer_state.multi_package_binaries_distribution(), true, |
| 708 post_install_task_list); | 720 post_install_task_list); |
| 709 } | 721 } |
| 710 } | 722 } |
| 711 | 723 |
| 712 return true; | 724 return true; |
| 713 } | 725 } |
| 714 | 726 |
| 715 void AddInstallWorkItems(const InstallationState& original_state, | 727 void AddChromeWorkItems(const InstallationState& original_state, |
| 716 const InstallerState& installer_state, | 728 const InstallerState& installer_state, |
| 717 const FilePath& setup_path, | 729 const FilePath& setup_path, |
| 718 const FilePath& archive_path, | 730 const FilePath& archive_path, |
| 719 const FilePath& src_path, | 731 const FilePath& src_path, |
| 720 const FilePath& temp_path, | 732 const FilePath& temp_path, |
| 721 const Version& new_version, | 733 const Version& new_version, |
| 722 scoped_ptr<Version>* current_version, | 734 scoped_ptr<Version>* current_version, |
| 723 WorkItemList* install_list) { | 735 WorkItemList* install_list) { |
| 724 DCHECK(install_list); | |
| 725 | |
| 726 const FilePath& target_path = installer_state.target_path(); | 736 const FilePath& target_path = installer_state.target_path(); |
| 727 | 737 |
| 728 // A temp directory that work items need and the actual install directory. | |
| 729 install_list->AddCreateDirWorkItem(temp_path); | |
| 730 install_list->AddCreateDirWorkItem(target_path); | |
| 731 | |
| 732 if (current_version != NULL && current_version->get() != NULL) { | 738 if (current_version != NULL && current_version->get() != NULL) { |
| 733 // Delete the archive from an existing install to save some disk space. We | 739 // Delete the archive from an existing install to save some disk space. We |
| 734 // make this an unconditional work item since there's no need to roll this | 740 // make this an unconditional work item since there's no need to roll this |
| 735 // back; if installation fails we'll be moved to the "-full" channel anyway. | 741 // back; if installation fails we'll be moved to the "-full" channel anyway. |
| 736 FilePath old_installer_dir( | 742 FilePath old_installer_dir( |
| 737 installer_state.GetInstallerDirectory(**current_version)); | 743 installer_state.GetInstallerDirectory(**current_version)); |
| 738 FilePath old_archive(old_installer_dir.Append(archive_path.BaseName())); | 744 FilePath old_archive(old_installer_dir.Append(installer::kChromeArchive)); |
| 739 install_list->AddDeleteTreeWorkItem(old_archive, temp_path) | 745 // Don't delete the archive that we are actually installing from. |
| 740 ->set_ignore_failure(true); | 746 if (archive_path != old_archive) { |
| 747 install_list->AddDeleteTreeWorkItem(old_archive, temp_path) |
| 748 ->set_ignore_failure(true); |
| 749 } |
| 741 } | 750 } |
| 742 | 751 |
| 743 // Delete any new_chrome.exe if present (we will end up creating a new one | 752 // Delete any new_chrome.exe if present (we will end up creating a new one |
| 744 // if required) and then copy chrome.exe | 753 // if required) and then copy chrome.exe |
| 745 FilePath new_chrome_exe(target_path.Append(installer::kChromeNewExe)); | 754 FilePath new_chrome_exe(target_path.Append(installer::kChromeNewExe)); |
| 746 | 755 |
| 747 install_list->AddDeleteTreeWorkItem(new_chrome_exe, temp_path); | 756 install_list->AddDeleteTreeWorkItem(new_chrome_exe, temp_path); |
| 748 | 757 |
| 749 if (installer_state.IsChromeFrameRunning(original_state)) { | 758 if (installer_state.IsChromeFrameRunning(original_state)) { |
| 750 VLOG(1) << "Chrome Frame in use. Copying to new_chrome.exe"; | 759 VLOG(1) << "Chrome Frame in use. Copying to new_chrome.exe"; |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 833 // Delete any old_chrome.exe if present (ignore failure if it's in use). | 842 // Delete any old_chrome.exe if present (ignore failure if it's in use). |
| 834 install_list->AddDeleteTreeWorkItem( | 843 install_list->AddDeleteTreeWorkItem( |
| 835 target_path.Append(installer::kChromeOldExe), temp_path) | 844 target_path.Append(installer::kChromeOldExe), temp_path) |
| 836 ->set_ignore_failure(true); | 845 ->set_ignore_failure(true); |
| 837 | 846 |
| 838 // Copy installer in install directory and | 847 // Copy installer in install directory and |
| 839 // add shortcut in Control Panel->Add/Remove Programs. | 848 // add shortcut in Control Panel->Add/Remove Programs. |
| 840 AddInstallerCopyTasks(installer_state, setup_path, archive_path, temp_path, | 849 AddInstallerCopyTasks(installer_state, setup_path, archive_path, temp_path, |
| 841 new_version, install_list); | 850 new_version, install_list); |
| 842 | 851 |
| 852 } |
| 853 |
| 854 void AddInstallWorkItems(const InstallationState& original_state, |
| 855 const InstallerState& installer_state, |
| 856 const FilePath& setup_path, |
| 857 const FilePath& archive_path, |
| 858 const FilePath& src_path, |
| 859 const FilePath& temp_path, |
| 860 const Version& new_version, |
| 861 scoped_ptr<Version>* current_version, |
| 862 WorkItemList* install_list) { |
| 863 DCHECK(install_list); |
| 864 |
| 865 const FilePath& target_path = installer_state.target_path(); |
| 866 |
| 867 // A temp directory that work items need and the actual install directory. |
| 868 install_list->AddCreateDirWorkItem(temp_path); |
| 869 install_list->AddCreateDirWorkItem(target_path); |
| 870 |
| 871 if (installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER) || |
| 872 installer_state.FindProduct(BrowserDistribution::CHROME_FRAME) || |
| 873 installer_state.FindProduct(BrowserDistribution::CHROME_BINARIES)) { |
| 874 AddChromeWorkItems(original_state, |
| 875 installer_state, |
| 876 setup_path, |
| 877 archive_path, |
| 878 src_path, |
| 879 temp_path, |
| 880 new_version, |
| 881 current_version, |
| 882 install_list); |
| 883 } |
| 884 |
| 885 if (installer_state.FindProduct(BrowserDistribution::CHROME_APP_HOST)) { |
| 886 install_list->AddCopyTreeWorkItem( |
| 887 src_path.Append(installer::kChromeAppHostExe).value(), |
| 888 target_path.Append(installer::kChromeAppHostExe).value(), |
| 889 temp_path.value(), |
| 890 WorkItem::ALWAYS, |
| 891 L""); |
| 892 } |
| 893 |
| 843 const HKEY root = installer_state.root_key(); | 894 const HKEY root = installer_state.root_key(); |
| 844 // Only set "lang" for user-level installs since for system-level, the install | 895 // Only set "lang" for user-level installs since for system-level, the install |
| 845 // language may not be related to a given user's runtime language. | 896 // language may not be related to a given user's runtime language. |
| 846 const bool add_language_identifier = !installer_state.system_install(); | 897 const bool add_language_identifier = !installer_state.system_install(); |
| 847 | 898 |
| 848 const Products& products = installer_state.products(); | 899 const Products& products = installer_state.products(); |
| 849 for (size_t i = 0; i < products.size(); ++i) { | 900 for (size_t i = 0; i < products.size(); ++i) { |
| 850 const Product* product = products[i]; | 901 const Product* product = products[i]; |
| 851 | 902 |
| 852 AddUninstallShortcutWorkItems(installer_state, setup_path, new_version, | 903 AddUninstallShortcutWorkItems(installer_state, setup_path, new_version, |
| 853 install_list, *product); | 904 install_list, *product); |
| 854 | 905 |
| 855 AddVersionKeyWorkItems(root, product->distribution(), new_version, | 906 AddVersionKeyWorkItems(root, product->distribution(), new_version, |
| 856 add_language_identifier, install_list); | 907 add_language_identifier, install_list); |
| 857 | 908 |
| 858 AddDelegateExecuteWorkItems(installer_state, src_path, new_version, | 909 AddDelegateExecuteWorkItems(installer_state, src_path, new_version, |
| 859 *product, install_list); | 910 *product, install_list); |
| 860 } | 911 } |
| 861 | 912 |
| 862 if (installer_state.is_multi_install()) { | |
| 863 AddMultiUninstallWorkItems(installer_state, setup_path, new_version, | |
| 864 install_list); | |
| 865 | |
| 866 AddVersionKeyWorkItems(root, | |
| 867 installer_state.multi_package_binaries_distribution(), new_version, | |
| 868 add_language_identifier, install_list); | |
| 869 } | |
| 870 | |
| 871 // Add any remaining work items that involve special settings for | 913 // Add any remaining work items that involve special settings for |
| 872 // each product. | 914 // each product. |
| 873 AddProductSpecificWorkItems(original_state, installer_state, setup_path, | 915 AddProductSpecificWorkItems(original_state, installer_state, setup_path, |
| 874 new_version, install_list); | 916 new_version, install_list); |
| 875 | 917 |
| 876 // Copy over brand, usagestats, and other values. | 918 // Copy over brand, usagestats, and other values. |
| 877 AddGoogleUpdateWorkItems(original_state, installer_state, install_list); | 919 AddGoogleUpdateWorkItems(original_state, installer_state, install_list); |
| 878 | 920 |
| 879 AddQuickEnableWorkItems(installer_state, original_state, &setup_path, | 921 AddQuickEnableApplicationHostWorkItems(installer_state, original_state, |
| 880 &new_version, install_list); | 922 &setup_path, &new_version, |
| 923 install_list); |
| 924 |
| 925 AddQuickEnableChromeFrameWorkItems(installer_state, original_state, |
| 926 &setup_path, &new_version, install_list); |
| 881 | 927 |
| 882 // Append the tasks that run after the installation. | 928 // Append the tasks that run after the installation. |
| 883 AppendPostInstallTasks(installer_state, | 929 AppendPostInstallTasks(installer_state, |
| 884 setup_path, | 930 setup_path, |
| 885 new_chrome_exe, | |
| 886 current_version->get(), | 931 current_version->get(), |
| 887 new_version, | 932 new_version, |
| 888 temp_path, | 933 temp_path, |
| 889 install_list); | 934 install_list); |
| 890 } | 935 } |
| 891 | 936 |
| 892 void AddRegisterComDllWorkItems(const FilePath& dll_folder, | 937 void AddRegisterComDllWorkItems(const FilePath& dll_folder, |
| 893 const std::vector<FilePath>& dll_list, | 938 const std::vector<FilePath>& dll_list, |
| 894 bool system_level, | 939 bool system_level, |
| 895 bool do_register, | 940 bool do_register, |
| (...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1289 } else { | 1334 } else { |
| 1290 VLOG(1) << kIERefreshPolicy << " not supported."; | 1335 VLOG(1) << kIERefreshPolicy << " not supported."; |
| 1291 } | 1336 } |
| 1292 | 1337 |
| 1293 FreeLibrary(ieframe); | 1338 FreeLibrary(ieframe); |
| 1294 } else { | 1339 } else { |
| 1295 VLOG(1) << "Cannot load " << kIEFrameDll; | 1340 VLOG(1) << "Cannot load " << kIEFrameDll; |
| 1296 } | 1341 } |
| 1297 } | 1342 } |
| 1298 | 1343 |
| 1299 void AddQuickEnableWorkItems(const InstallerState& installer_state, | 1344 void AddGenericQuickEnableWorkItems(const InstallerState& installer_state, |
| 1300 const InstallationState& machine_state, | 1345 const InstallationState& machine_state, |
| 1301 const FilePath* setup_path, | 1346 const FilePath* setup_path, |
| 1302 const Version* new_version, | 1347 const Version* new_version, |
| 1303 WorkItemList* work_item_list) { | 1348 WorkItemList* work_item_list, |
| 1349 bool have_child_product, |
| 1350 const CommandLine& child_product_switches, |
| 1351 const std::wstring& command_id) { |
| 1304 DCHECK(setup_path || | 1352 DCHECK(setup_path || |
| 1305 installer_state.operation() == InstallerState::UNINSTALL); | 1353 installer_state.operation() == InstallerState::UNINSTALL); |
| 1306 DCHECK(new_version || | 1354 DCHECK(new_version || |
| 1307 installer_state.operation() == InstallerState::UNINSTALL); | 1355 installer_state.operation() == InstallerState::UNINSTALL); |
| 1308 DCHECK(work_item_list); | 1356 DCHECK(work_item_list); |
| 1309 | 1357 |
| 1310 const bool system_install = installer_state.system_install(); | 1358 const bool system_install = installer_state.system_install(); |
| 1311 bool have_multi_chrome = false; | 1359 bool have_chrome_binaries = false; |
| 1312 bool have_chrome_frame = false; | |
| 1313 | 1360 |
| 1314 // STEP 1: Figure out the state of the machine before the operation. | 1361 // STEP 1: Figure out the state of the machine before the operation. |
| 1315 const ProductState* product_state = NULL; | 1362 const ProductState* product_state = NULL; |
| 1316 | 1363 |
| 1317 // Is multi-install Chrome already on the machine? | 1364 // Are the Chrome Binaries already on the machine? |
| 1318 product_state = | 1365 product_state = |
| 1319 machine_state.GetProductState(system_install, | 1366 machine_state.GetProductState(system_install, |
| 1320 BrowserDistribution::CHROME_BROWSER); | 1367 BrowserDistribution::CHROME_BINARIES); |
| 1321 if (product_state != NULL && product_state->is_multi_install()) | 1368 if (product_state != NULL && product_state->is_multi_install()) |
| 1322 have_multi_chrome = true; | 1369 have_chrome_binaries = true; |
| 1323 | |
| 1324 // Is Chrome Frame !ready-mode already on the machine? | |
| 1325 product_state = | |
| 1326 machine_state.GetProductState(system_install, | |
| 1327 BrowserDistribution::CHROME_FRAME); | |
| 1328 if (product_state != NULL && | |
| 1329 !product_state->uninstall_command().HasSwitch( | |
| 1330 switches::kChromeFrameReadyMode)) | |
| 1331 have_chrome_frame = true; | |
| 1332 | 1370 |
| 1333 // STEP 2: Now take into account the current operation. | 1371 // STEP 2: Now take into account the current operation. |
| 1334 const Product* product = NULL; | 1372 const Product* product = NULL; |
| 1335 | 1373 |
| 1336 if (installer_state.operation() == InstallerState::UNINSTALL) { | 1374 if (installer_state.operation() == InstallerState::UNINSTALL) { |
| 1337 // Forget about multi-install Chrome if it is being uninstalled. | 1375 // Forget about multi-install Chrome if it is being uninstalled. |
| 1338 product = | 1376 product = |
| 1339 installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER); | 1377 installer_state.FindProduct(BrowserDistribution::CHROME_BINARIES); |
| 1340 if (product != NULL && installer_state.is_multi_install()) | 1378 if (product != NULL && installer_state.is_multi_install()) |
| 1341 have_multi_chrome = false; | 1379 have_chrome_binaries = false; |
| 1342 | |
| 1343 // Forget about Chrome Frame if it is being uninstalled. Note that we don't | |
| 1344 // bother to check !HasOption(kOptionReadyMode) since have_chrome_frame | |
| 1345 // should have been false for that case in the first place. It's odd if it | |
| 1346 // wasn't, but the right thing to do in that case is to proceed with the | |
| 1347 // thought that CF will not be installed in any sense when we reach the | |
| 1348 // finish line. | |
| 1349 if (installer_state.FindProduct(BrowserDistribution::CHROME_FRAME) != NULL) | |
| 1350 have_chrome_frame = false; | |
| 1351 } else { | 1380 } else { |
| 1352 // Check if we're installing multi-install Chrome. | 1381 // Check if we're installing Chrome Binaries |
| 1353 product = | 1382 product = |
| 1354 installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER); | 1383 installer_state.FindProduct(BrowserDistribution::CHROME_BINARIES); |
| 1355 if (product != NULL && installer_state.is_multi_install()) | 1384 if (product != NULL && installer_state.is_multi_install()) |
| 1356 have_multi_chrome = true; | 1385 have_chrome_binaries = true; |
| 1357 | |
| 1358 // Check if we're installing Chrome Frame !ready-mode. | |
| 1359 product = installer_state.FindProduct(BrowserDistribution::CHROME_FRAME); | |
| 1360 if (product != NULL && !product->HasOption(kOptionReadyMode)) | |
| 1361 have_chrome_frame = true; | |
| 1362 } | 1386 } |
| 1363 | 1387 |
| 1364 // STEP 3: Decide what to do based on the final state of things. | 1388 // STEP 3: Decide what to do based on the final state of things. |
| 1365 enum QuickEnableOperation { | 1389 enum QuickEnableOperation { |
| 1366 DO_NOTHING, | 1390 DO_NOTHING, |
| 1367 ADD_COMMAND, | 1391 ADD_COMMAND, |
| 1368 REMOVE_COMMAND | 1392 REMOVE_COMMAND |
| 1369 } operation = DO_NOTHING; | 1393 } operation = DO_NOTHING; |
| 1370 FilePath binaries_setup_path; | 1394 FilePath binaries_setup_path; |
| 1371 | 1395 |
| 1372 if (have_chrome_frame) { | 1396 if (have_child_product) { |
| 1373 // Chrome Frame !ready-mode is or will be installed. Unconditionally remove | 1397 // Child product is being uninstalled. Unconditionally remove the Quick |
| 1374 // the quick-enable-cf command from the binaries. We do this even if | 1398 // Enable command from the binaries. We do this even if multi-install Chrome |
| 1375 // multi-install Chrome isn't installed since we don't want them left | 1399 // isn't installed since we don't want them left behind in any case. |
| 1376 // behind in any case. | |
| 1377 operation = REMOVE_COMMAND; | 1400 operation = REMOVE_COMMAND; |
| 1378 } else if (have_multi_chrome) { | 1401 } else if (have_chrome_binaries) { |
| 1379 // Chrome Frame isn't (to be) installed or is (to be) installed only in | 1402 // Child product isn't (to be) installed while multi-install Chrome is (to |
| 1380 // ready-mode, while multi-install Chrome is (to be) installed. Add the | 1403 // be) installed. Add the Quick Enable command to the binaries. |
| 1381 // quick-enable-cf command to the binaries. | |
| 1382 operation = ADD_COMMAND; | 1404 operation = ADD_COMMAND; |
| 1383 // The path to setup.exe contains the version of the Chrome binaries, so it | 1405 // The path to setup.exe contains the version of the Chrome binaries, so it |
| 1384 // takes a little work to get it right. | 1406 // takes a little work to get it right. |
| 1385 if (installer_state.operation() == InstallerState::UNINSTALL) { | 1407 if (installer_state.operation() == InstallerState::UNINSTALL) { |
| 1386 // Chrome Frame is being uninstalled. Use the path to the currently | 1408 // One or more products are being uninstalled, but not the binaries. Use |
| 1387 // installed Chrome setup.exe. | 1409 // the path to the currently installed Chrome setup.exe. |
| 1388 product_state = | 1410 product_state = |
| 1389 machine_state.GetProductState(system_install, | 1411 machine_state.GetProductState(system_install, |
| 1390 BrowserDistribution::CHROME_BROWSER); | 1412 BrowserDistribution::CHROME_BINARIES); |
| 1391 DCHECK(product_state); | 1413 DCHECK(product_state); |
| 1392 binaries_setup_path = product_state->uninstall_command().GetProgram(); | 1414 binaries_setup_path = product_state->uninstall_command().GetProgram(); |
| 1393 } else { | 1415 } else { |
| 1394 // Chrome is being installed, updated, or otherwise being operated on. | 1416 // Chrome Binaries are being installed, updated, or otherwise operated on. |
| 1395 // Use the path to the given |setup_path| in the normal location of | 1417 // Use the path to the given |setup_path| in the normal location of |
| 1396 // multi-install Chrome of the given |version|. | 1418 // multi-install Chrome Binaries of the given |version|. |
| 1397 DCHECK(installer_state.is_multi_install()); | 1419 DCHECK(installer_state.is_multi_install()); |
| 1398 binaries_setup_path = | 1420 binaries_setup_path = |
| 1399 installer_state.GetInstallerDirectory(*new_version).Append( | 1421 installer_state.GetInstallerDirectory(*new_version).Append( |
| 1400 setup_path->BaseName()); | 1422 setup_path->BaseName()); |
| 1401 } | 1423 } |
| 1402 } | 1424 } |
| 1403 | 1425 |
| 1404 // STEP 4: Take action. | 1426 // STEP 4: Take action. |
| 1405 if (operation != DO_NOTHING) { | 1427 if (operation != DO_NOTHING) { |
| 1406 // Get the path to the quick-enable-cf command for the binaries. | 1428 // Get the path to the quick-enable-cf command for the binaries. |
| 1407 BrowserDistribution* binaries = | 1429 BrowserDistribution* binaries = |
| 1408 BrowserDistribution::GetSpecificDistribution( | 1430 BrowserDistribution::GetSpecificDistribution( |
| 1409 BrowserDistribution::CHROME_BINARIES); | 1431 BrowserDistribution::CHROME_BINARIES); |
| 1410 std::wstring cmd_key(binaries->GetVersionKey()); | 1432 std::wstring cmd_key(binaries->GetVersionKey()); |
| 1411 cmd_key.append(1, L'\\').append(google_update::kRegCommandsKey) | 1433 cmd_key.append(1, L'\\').append(google_update::kRegCommandsKey) |
| 1412 .append(1, L'\\').append(kCmdQuickEnableCf); | 1434 .append(1, L'\\').append(command_id); |
| 1413 | 1435 |
| 1414 if (operation == ADD_COMMAND) { | 1436 if (operation == ADD_COMMAND) { |
| 1415 DCHECK(!binaries_setup_path.empty()); | 1437 DCHECK(!binaries_setup_path.empty()); |
| 1416 CommandLine cmd_line(binaries_setup_path); | 1438 CommandLine cmd_line(binaries_setup_path); |
| 1417 cmd_line.AppendSwitch(switches::kMultiInstall); | 1439 cmd_line.AppendArguments(child_product_switches, |
| 1418 if (installer_state.system_install()) | 1440 false); // include_program |
| 1419 cmd_line.AppendSwitch(switches::kSystemLevel); | |
| 1420 if (installer_state.verbose_logging()) | 1441 if (installer_state.verbose_logging()) |
| 1421 cmd_line.AppendSwitch(switches::kVerboseLogging); | 1442 cmd_line.AppendSwitch(switches::kVerboseLogging); |
| 1422 cmd_line.AppendSwitch(switches::kChromeFrameQuickEnable); | |
| 1423 AppCommand cmd(cmd_line.GetCommandLineString(), true, true); | 1443 AppCommand cmd(cmd_line.GetCommandLineString(), true, true); |
| 1424 cmd.AddWorkItems(installer_state.root_key(), cmd_key, work_item_list); | 1444 cmd.AddWorkItems(installer_state.root_key(), cmd_key, work_item_list); |
| 1425 } else { | 1445 } else { |
| 1426 DCHECK(operation == REMOVE_COMMAND); | 1446 DCHECK(operation == REMOVE_COMMAND); |
| 1427 work_item_list->AddDeleteRegKeyWorkItem(installer_state.root_key(), | 1447 work_item_list->AddDeleteRegKeyWorkItem(installer_state.root_key(), |
| 1428 cmd_key)->set_log_message( | 1448 cmd_key)->set_log_message( |
| 1429 "removing quick-enable-cf command"); | 1449 "removing " + WideToASCII(command_id) + " command"); |
| 1430 } | 1450 } |
| 1431 } | 1451 } |
| 1432 } | 1452 } |
| 1433 | 1453 |
| 1454 void AddQuickEnableChromeFrameWorkItems(const InstallerState& installer_state, |
| 1455 const InstallationState& machine_state, |
| 1456 const FilePath* setup_path, |
| 1457 const Version* new_version, |
| 1458 WorkItemList* work_item_list) { |
| 1459 DCHECK(setup_path || |
| 1460 installer_state.operation() == InstallerState::UNINSTALL); |
| 1461 DCHECK(new_version || |
| 1462 installer_state.operation() == InstallerState::UNINSTALL); |
| 1463 DCHECK(work_item_list); |
| 1464 |
| 1465 const bool system_install = installer_state.system_install(); |
| 1466 bool have_chrome_frame = false; |
| 1467 |
| 1468 // STEP 1: Figure out the state of the machine before the operation. |
| 1469 const ProductState* product_state = NULL; |
| 1470 |
| 1471 // Is Chrome Frame !ready-mode already on the machine? |
| 1472 product_state = |
| 1473 machine_state.GetProductState(system_install, |
| 1474 BrowserDistribution::CHROME_FRAME); |
| 1475 if (product_state != NULL && |
| 1476 !product_state->uninstall_command().HasSwitch( |
| 1477 switches::kChromeFrameReadyMode)) |
| 1478 have_chrome_frame = true; |
| 1479 |
| 1480 // STEP 2: Now take into account the current operation. |
| 1481 const Product* product = NULL; |
| 1482 |
| 1483 if (installer_state.operation() == InstallerState::UNINSTALL) { |
| 1484 // Forget about Chrome Frame if it is being uninstalled. Note that we don't |
| 1485 // bother to check !HasOption(kOptionReadyMode) since have_chrome_frame |
| 1486 // should have been false for that case in the first place. It's odd if it |
| 1487 // wasn't, but the right thing to do in that case is to proceed with the |
| 1488 // thought that CF will not be installed in any sense when we reach the |
| 1489 // finish line. |
| 1490 if (installer_state.FindProduct(BrowserDistribution::CHROME_FRAME) != NULL) |
| 1491 have_chrome_frame = false; |
| 1492 } else { |
| 1493 // Check if we're installing Chrome Frame !ready-mode. |
| 1494 product = installer_state.FindProduct(BrowserDistribution::CHROME_FRAME); |
| 1495 if (product != NULL && !product->HasOption(kOptionReadyMode)) |
| 1496 have_chrome_frame = true; |
| 1497 } |
| 1498 |
| 1499 CommandLine cmd_line(CommandLine::NO_PROGRAM); |
| 1500 cmd_line.AppendSwitch(switches::kMultiInstall); |
| 1501 if (installer_state.system_install()) |
| 1502 cmd_line.AppendSwitch(switches::kSystemLevel); |
| 1503 cmd_line.AppendSwitch(switches::kChromeFrameQuickEnable); |
| 1504 |
| 1505 AddGenericQuickEnableWorkItems(installer_state, |
| 1506 machine_state, |
| 1507 setup_path, |
| 1508 new_version, |
| 1509 work_item_list, |
| 1510 have_chrome_frame, |
| 1511 cmd_line, |
| 1512 kCmdQuickEnableCf); |
| 1513 } |
| 1514 |
| 1515 void AddQuickEnableApplicationHostWorkItems( |
| 1516 const InstallerState& installer_state, |
| 1517 const InstallationState& machine_state, |
| 1518 const FilePath* setup_path, |
| 1519 const Version* new_version, |
| 1520 WorkItemList* work_item_list) { |
| 1521 DCHECK(setup_path || |
| 1522 installer_state.operation() == InstallerState::UNINSTALL); |
| 1523 DCHECK(new_version || |
| 1524 installer_state.operation() == InstallerState::UNINSTALL); |
| 1525 DCHECK(work_item_list); |
| 1526 |
| 1527 CommandLine cmd_line(CommandLine::NO_PROGRAM); |
| 1528 cmd_line.AppendSwitch(switches::kMultiInstall); |
| 1529 cmd_line.AppendSwitch(switches::kChromeAppHost); |
| 1530 |
| 1531 // For system-level binaries there is no way to keep the command state in sync |
| 1532 // with the installation/uninstallation of the Application Host (which is |
| 1533 // always at user-level). |
| 1534 // So we pass false for 'have_child_product' to cause this command to always |
| 1535 // be installed if the Chrome Binaries are installed. |
| 1536 AddGenericQuickEnableWorkItems(installer_state, |
| 1537 machine_state, |
| 1538 setup_path, |
| 1539 new_version, |
| 1540 work_item_list, |
| 1541 false, // have_child_product |
| 1542 cmd_line, |
| 1543 kCmdQuickEnableApplicationHost); |
| 1544 } |
| 1545 |
| 1434 } // namespace installer | 1546 } // namespace installer |
| OLD | NEW |