Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(152)

Side by Side Diff: chrome/installer/setup/setup_main.cc

Issue 10806086: Fix multi-install update regression. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 #include <windows.h> 5 #include <windows.h>
6 #include <msi.h> 6 #include <msi.h>
7 #include <shellapi.h> 7 #include <shellapi.h>
8 #include <shlobj.h> 8 #include <shlobj.h>
9 9
10 #include "base/at_exit.h" 10 #include "base/at_exit.h"
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 // Delete an elevation policy associated with the old version, should one 210 // Delete an elevation policy associated with the old version, should one
211 // exist. 211 // exist.
212 if (installer_state->FindProduct(BrowserDistribution::CHROME_FRAME)) { 212 if (installer_state->FindProduct(BrowserDistribution::CHROME_FRAME)) {
213 installer::AddDeleteOldIELowRightsPolicyWorkItems(*installer_state, 213 installer::AddDeleteOldIELowRightsPolicyWorkItems(*installer_state,
214 install_list.get()); 214 install_list.get());
215 } 215 }
216 // old_chrome.exe is still in use in most cases, so ignore failures here. 216 // old_chrome.exe is still in use in most cases, so ignore failures here.
217 install_list->AddDeleteTreeWorkItem(chrome_old_exe, temp_path.path()) 217 install_list->AddDeleteTreeWorkItem(chrome_old_exe, temp_path.path())
218 ->set_ignore_failure(true); 218 ->set_ignore_failure(true);
219 219
220 // Collect the set of distributions we need to update, which is the 220 // Collect the set of distributions we need to update, which is all
221 // multi-install binaries (if this is a multi-install operation) and all 221 // products we're operating on (this includes the multi-install binaries).
222 // products we're operating on.
223 BrowserDistribution* dists[BrowserDistribution::NUM_TYPES]; 222 BrowserDistribution* dists[BrowserDistribution::NUM_TYPES];
224 int num_dists = 0; 223 int num_dists = 0;
225 // First, add the multi-install binaries, if relevant. 224 // std::transform can handily do this for us, but this is discouraged as
226 if (installer_state->is_multi_install()) 225 // being too tricky.
robertshield 2012/07/24 17:16:50 Grumbling noted, but the above comment doesn't mak
grt (UTC plus 2) 2012/07/24 20:31:29 I briefly changed the comment to "I hate robertshi
robertshield 2012/07/24 21:03:14 concise != readable
grt (UTC plus 2) 2012/07/24 21:06:00 LOL, BFF
227 dists[num_dists++] = installer_state->multi_package_binaries_distribution();
228 // Next, add all products we're operating on. std::transform can handily do
229 // this for us, but this is discouraged as being too tricky.
230 const Products& products = installer_state->products(); 226 const Products& products = installer_state->products();
231 for (Products::size_type i = 0; i < products.size(); ++i) { 227 CHECK_LE(products.size(), arraysize(dists));
228 for (size_t i = 0; i < products.size(); ++i)
232 dists[num_dists++] = products[i]->distribution(); 229 dists[num_dists++] = products[i]->distribution();
robertshield 2012/07/24 17:16:50 nit: It seems to me that num_dists could be done a
grt (UTC plus 2) 2012/07/24 20:31:29 What?!?? There's a forest around these trees? D
233 }
234 230
235 // Add work items to delete the "opv", "cpv", and "cmd" values from all 231 // Add work items to delete the "opv", "cpv", and "cmd" values from all
236 // distributions. 232 // distributions.
237 HKEY reg_root = installer_state->root_key(); 233 HKEY reg_root = installer_state->root_key();
238 string16 version_key; 234 string16 version_key;
239 for (int i = 0; i < num_dists; ++i) { 235 for (int i = 0; i < num_dists; ++i) {
240 version_key = dists[i]->GetVersionKey(); 236 version_key = dists[i]->GetVersionKey();
241 install_list->AddDeleteRegValueWorkItem( 237 install_list->AddDeleteRegValueWorkItem(
242 reg_root, version_key, google_update::kRegOldVersionField); 238 reg_root, version_key, google_update::kRegOldVersionField);
243 install_list->AddDeleteRegValueWorkItem( 239 install_list->AddDeleteRegValueWorkItem(
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 const ProductState* chrome_state = 368 const ProductState* chrome_state =
373 original_state.GetProductState(system_level, 369 original_state.GetProductState(system_level,
374 BrowserDistribution::CHROME_BROWSER); 370 BrowserDistribution::CHROME_BROWSER);
375 371
376 if (!binaries) { 372 if (!binaries) {
377 if (app_host && !chrome && !chrome_frame && !cf_state && !chrome_state) { 373 if (app_host && !chrome && !chrome_frame && !cf_state && !chrome_state) {
378 DCHECK(!system_level); 374 DCHECK(!system_level);
379 // App Host may use Chrome/Chrome binaries at system-level. 375 // App Host may use Chrome/Chrome binaries at system-level.
380 if (original_state.GetProductState( 376 if (original_state.GetProductState(
381 true, // system 377 true, // system
382 BrowserDistribution::CHROME_BROWSER) || 378 BrowserDistribution::CHROME_BROWSER) ||
robertshield 2012/07/24 17:16:50 Shouldn't this only be checking for the "Chrome bi
grt (UTC plus 2) 2012/07/24 20:31:29 I discussed this with Erik, and I believe that thi
383 original_state.GetProductState( 379 original_state.GetProductState(
384 true, // system 380 true, // system
385 BrowserDistribution::CHROME_BINARIES)) { 381 BrowserDistribution::CHROME_BINARIES)) {
382 VLOG(1) << "Installing/updating Application Host without binaries.";
386 return true; 383 return true;
387 } else { 384 } else {
385 // Somehow the binaries were present when the quick-enable app host
386 // command was run, but now they appear to be missing.
387 // TODO(erikwright): should the binaries be implicitly added?
388 LOG(ERROR) << "Cannot install Application Host without binaries.";
389 *status = installer::APP_HOST_REQUIRES_BINARIES;
390 installer_state->WriteInstallerResult(*status, 0, NULL);
388 return false; 391 return false;
389 } 392 }
390 } else { 393 } else {
391 // Every other scenario requires the binaries to be installed/updated 394 // Every other scenario requires the binaries to be installed/updated
392 // simultaneous to the main product. 395 // simultaneous to the main product. This will only be hit if
393 return false; 396 // --multi-install is given with no products. see
robertshield 2012/07/24 17:16:50 nit: simultaneous -> simultaneously, see -> See
grt (UTC plus 2) 2012/07/24 20:31:29 Done.
397 // CheckPreInstallConditions for handling of this case.
398 return true;
394 } 399 }
395 } 400 }
396 401
397 if (chrome) { 402 if (chrome) {
398 if (chrome_frame && 403 if (chrome_frame &&
399 chrome_frame->HasOption(installer::kOptionReadyMode)) { 404 chrome_frame->HasOption(installer::kOptionReadyMode)) {
400 // We're being asked to install Chrome with Chrome Frame in ready-mode. 405 // We're being asked to install Chrome with Chrome Frame in ready-mode.
401 // This is an optimistic operation: if a SxS install of Chrome Frame 406 // This is an optimistic operation: if a SxS install of Chrome Frame
402 // is already present, don't touch it; if a multi-install of Chrome 407 // is already present, don't touch it; if a multi-install of Chrome
403 // Frame is present, preserve its settings (ready-mode). 408 // Frame is present, preserve its settings (ready-mode).
404 if (cf_state != NULL) { 409 if (cf_state != NULL) {
405 installer_state->RemoveProduct(chrome_frame); 410 installer_state->RemoveProduct(chrome_frame);
406 chrome_frame = NULL; 411 chrome_frame = NULL;
407 if (cf_state->is_multi_install()) { 412 if (cf_state->is_multi_install()) {
408 chrome_frame = installer_state->AddProductFromState( 413 chrome_frame = installer_state->AddProductFromState(
409 BrowserDistribution::CHROME_FRAME, *cf_state); 414 BrowserDistribution::CHROME_FRAME, *cf_state);
410 VLOG(1) << "Upgrading existing multi-install Chrome Frame rather " 415 VLOG(1) << "Upgrading existing multi-install Chrome Frame rather "
411 "than installing in ready-mode."; 416 "than installing in ready-mode.";
412 } else { 417 } else {
413 VLOG(1) << "Skipping upgrade of single-install Chrome Frame rather " 418 VLOG(1) << "Skipping upgrade of single-install Chrome Frame rather "
414 "than installing in ready-mode."; 419 "than installing in ready-mode.";
415 } 420 }
416 } else { 421 } else {
417 VLOG(1) << "Performing initial install of Chrome Frame ready-mode."; 422 VLOG(1) << "Performing initial install of Chrome Frame ready-mode.";
418 } 423 }
419 } 424 }
420 } else if (chrome_state != NULL) { 425 } else if (chrome_state) {
421 // Chrome Frame is being installed in multi-install mode, and Chrome is 426 // Chrome Frame or the Application Host is being installed in
robertshield 2012/07/24 17:16:50 "Chrome Frame or the Application Host" -> "A produ
grt (UTC plus 2) 2012/07/24 20:31:29 Done.
422 // already present. Add Chrome to the set of products (making it 427 // multi-install mode, and Chrome is already present. Add Chrome to the
423 // multi-install in the process) so that it is updated, too. 428 // set of products (making it multi-install in the process) so that it is
429 // updated, too.
424 scoped_ptr<Product> multi_chrome(new Product( 430 scoped_ptr<Product> multi_chrome(new Product(
425 BrowserDistribution::GetSpecificDistribution( 431 BrowserDistribution::GetSpecificDistribution(
426 BrowserDistribution::CHROME_BROWSER))); 432 BrowserDistribution::CHROME_BROWSER)));
427 multi_chrome->SetOption(installer::kOptionMultiInstall, true); 433 multi_chrome->SetOption(installer::kOptionMultiInstall, true);
428 chrome = installer_state->AddProduct(&multi_chrome); 434 chrome = installer_state->AddProduct(&multi_chrome);
429 VLOG(1) << "Upgrading existing Chrome browser in multi-install mode."; 435 VLOG(1) << "Upgrading existing Chrome browser in multi-install mode.";
430 } else if (chrome_frame && 436 } else if (chrome_frame &&
431 chrome_frame->HasOption(installer::kOptionReadyMode)) { 437 chrome_frame->HasOption(installer::kOptionReadyMode)) {
432 // Chrome Frame with ready-mode is to be installed, yet Chrome is 438 // Chrome Frame with ready-mode is to be installed, yet Chrome is
433 // neither installed nor being installed. Fail. 439 // neither installed nor being installed. Fail.
434 LOG(ERROR) << "Cannot install Chrome Frame in ready mode without Chrome."; 440 LOG(ERROR) << "Cannot install Chrome Frame in ready mode without Chrome.";
435 *status = installer::READY_MODE_REQUIRES_CHROME; 441 *status = installer::READY_MODE_REQUIRES_CHROME;
436 installer_state->WriteInstallerResult( 442 installer_state->WriteInstallerResult(
437 *status, IDS_INSTALL_READY_MODE_REQUIRES_CHROME_BASE, NULL); 443 *status, IDS_INSTALL_READY_MODE_REQUIRES_CHROME_BASE, NULL);
438 return false; 444 return false;
439 } 445 }
440 446
441 // Fail if we're installing Chrome Frame when a single-install of it is 447 // Fail if we're installing Chrome Frame when a single-install of it is
442 // already installed. 448 // already installed.
443 // TODO(grt): Add support for migration of Chrome Frame from single- to
grt (UTC plus 2) 2012/07/24 15:02:03 we've decided not to do this, i believe.
444 // multi-install.
445 if (chrome_frame && cf_state && !cf_state->is_multi_install()) { 449 if (chrome_frame && cf_state && !cf_state->is_multi_install()) {
446 LOG(ERROR) << "Cannot migrate existing Chrome Frame installation to " 450 LOG(ERROR) << "Cannot migrate existing Chrome Frame installation to "
447 << "multi-install."; 451 << "multi-install.";
448 *status = installer::NON_MULTI_INSTALLATION_EXISTS; 452 *status = installer::NON_MULTI_INSTALLATION_EXISTS;
449 installer_state->WriteInstallerResult(*status, 453 installer_state->WriteInstallerResult(*status,
450 IDS_INSTALL_NON_MULTI_INSTALLATION_EXISTS_BASE, NULL); 454 IDS_INSTALL_NON_MULTI_INSTALLATION_EXISTS_BASE, NULL);
451 return false; 455 return false;
452 } 456 }
453 } else { 457 } else {
454 // This is a non-multi installation. 458 // This is a non-multi installation.
455 459
456 // It isn't possible to stuff two products into a single-install 460 // It isn't possible to stuff two products into a single-install
457 // InstallerState. Abort the process here in debug builds just in case 461 // InstallerState. Abort the process here in debug builds just in case
458 // someone finds a way. 462 // someone finds a way.
459 DCHECK_EQ(1U, products.size()); 463 DCHECK_EQ(1U, products.size());
460 if (products.size() != 1)
grt (UTC plus 2) 2012/07/24 15:02:03 erik added this, but i don't think it's necessary.
robertshield 2012/07/24 17:16:50 I believe you, but that isn't obvious from reading
grt (UTC plus 2) 2012/07/24 20:31:29 What part of "It isn't possible" do you not unders
robertshield 2012/07/24 21:03:14 I typically come across comments stating that "X i
grt (UTC plus 2) 2012/07/24 21:06:00 remind me to work on shutdown next.
461 return false;
462 464
463 // Check for an existing installation of the product. 465 // Check for an existing installation of the product.
464 const ProductState* product_state = original_state.GetProductState( 466 const ProductState* product_state = original_state.GetProductState(
465 system_level, products[0]->distribution()->GetType()); 467 system_level, products[0]->distribution()->GetType());
466 if (product_state != NULL) { 468 if (product_state != NULL) {
467 // Block downgrades from multi-install to single-install. 469 // Block downgrades from multi-install to single-install.
468 if (product_state->is_multi_install()) { 470 if (product_state->is_multi_install()) {
469 LOG(ERROR) << "Multi-install " 471 LOG(ERROR) << "Multi-install "
470 << products[0]->distribution()->GetAppShortCutName() 472 << products[0]->distribution()->GetAppShortCutName()
471 << " exists; aborting single install."; 473 << " exists; aborting single install.";
472 *status = installer::MULTI_INSTALLATION_EXISTS; 474 *status = installer::MULTI_INSTALLATION_EXISTS;
473 installer_state->WriteInstallerResult(*status, 475 installer_state->WriteInstallerResult(*status,
474 IDS_INSTALL_MULTI_INSTALLATION_EXISTS_BASE, NULL); 476 IDS_INSTALL_MULTI_INSTALLATION_EXISTS_BASE, NULL);
475 return false; 477 return false;
476 } 478 }
477 } 479 }
480 }
481
482 return true;
483 }
484
485 // Checks app host pre-install conditions, specifically that this is a
486 // user-level multi-install. When the pre-install conditions are not
487 // satisfied, the result is written to the registry (via WriteInstallerResult),
488 // |status| is set appropriately, and false is returned.
489 bool CheckAppHostPreconditions(const InstallationState& original_state,
490 InstallerState* installer_state,
491 installer::InstallStatus* status) {
492 if (installer_state->FindProduct(BrowserDistribution::CHROME_APP_HOST)) {
493
494 if (!installer_state->is_multi_install()) {
495 LOG(DFATAL) << "Application Host requires multi install";
grt (UTC plus 2) 2012/07/24 15:02:03 this means we're invoking ourselves wrong, which i
496 *status = installer::APP_HOST_REQUIRES_MULTI_INSTALL;
497 // No message string since there is nothing a user can do.
498 installer_state->WriteInstallerResult(*status, 0, NULL);
499 return false;
500 }
501
502 if (installer_state->system_install()) {
503 LOG(DFATAL) << "Application Host may only be installed at user-level.";
504 *status = installer::APP_HOST_REQUIRES_USER_LEVEL;
505 // No message string since there is nothing a user can do.
506 installer_state->WriteInstallerResult(*status, 0, NULL);
507 return false;
508 }
478 509
479 } 510 }
480 511
481 return true; 512 return true;
482 }
483
484 bool CheckAppHostPreconditions(const InstallationState& original_state,
485 InstallerState* installer_state) {
486 if (!installer_state->FindProduct(BrowserDistribution::CHROME_APP_HOST))
487 return true;
488
489 if (!installer_state->is_multi_install()) {
490 VLOG(1) << "Application Host may only be installed in multi-install mode.";
491 return false;
492 }
493
494 if (installer_state->system_install()) {
495 VLOG(1) << "Application Host may only be installed at user-level.";
496 return false;
497 }
498
499 return true;
500 } 513 }
501 514
502 // Checks for compatibility between the current state of the system and the 515 // Checks for compatibility between the current state of the system and the
503 // desired operation. Also applies policy that mutates the desired operation; 516 // desired operation. Also applies policy that mutates the desired operation;
504 // specifically, the |installer_state| object. 517 // specifically, the |installer_state| object.
505 // Also blocks simultaneous user-level and system-level installs. In the case 518 // Also blocks simultaneous user-level and system-level installs. In the case
506 // of trying to install user-level Chrome when system-level exists, the 519 // of trying to install user-level Chrome when system-level exists, the
507 // existing system-level Chrome is launched. 520 // existing system-level Chrome is launched.
508 // When the pre-install conditions are not satisfied, the result is written to 521 // When the pre-install conditions are not satisfied, the result is written to
509 // the registry (via WriteInstallerResult), |status| is set appropriately, and 522 // the registry (via WriteInstallerResult), |status| is set appropriately, and
510 // false is returned. 523 // false is returned.
511 bool CheckPreInstallConditions(const InstallationState& original_state, 524 bool CheckPreInstallConditions(const InstallationState& original_state,
512 InstallerState* installer_state, 525 InstallerState* installer_state,
513 installer::InstallStatus* status) { 526 installer::InstallStatus* status) {
514 if (!CheckAppHostPreconditions(original_state, installer_state)) 527 if (!CheckAppHostPreconditions(original_state, installer_state, status)) {
528 DCHECK_NE(*status, installer::UNKNOWN_STATUS);
515 return false; 529 return false;
530 }
516 531
517 if (!CheckMultiInstallConditions(original_state, installer_state, status)) 532 // See what products are already installed in multi mode. When we do multi
533 // installs, we must upgrade all installations since they share the binaries.
534 AddExistingMultiInstalls(original_state, installer_state);
robertshield 2012/07/24 17:16:50 Out of curiosity, how did this work before with Ch
grt (UTC plus 2) 2012/07/24 20:31:29 It didn't -- this was the change that broke dev ch
535
536 if (!CheckMultiInstallConditions(original_state, installer_state, status)) {
537 DCHECK_NE(*status, installer::UNKNOWN_STATUS);
518 return false; 538 return false;
539 }
519 540
520 const Products& products = installer_state->products(); 541 const Products& products = installer_state->products();
521 if (products.empty()) { 542 if (products.empty()) {
522 // We haven't been given any products on which to operate. 543 // We haven't been given any products on which to operate.
523 LOG(ERROR) 544 LOG(ERROR)
524 << "Not given any products to install and no products found to update."; 545 << "Not given any products to install and no products found to update.";
525 *status = installer::CHROME_NOT_INSTALLED; 546 *status = installer::CHROME_NOT_INSTALLED;
526 installer_state->WriteInstallerResult(*status, 547 installer_state->WriteInstallerResult(*status,
527 IDS_INSTALL_NO_PRODUCTS_TO_UPDATE_BASE, NULL); 548 IDS_INSTALL_NO_PRODUCTS_TO_UPDATE_BASE, NULL);
528 return false; 549 return false;
529 } 550 }
530 551
531 // See what products are already installed in multi mode. When we do multi
532 // installs, we must upgrade all installations since they share the binaries.
533 AddExistingMultiInstalls(original_state, installer_state);
534
535 if (!installer_state->system_install()) { 552 if (!installer_state->system_install()) {
536 // This is a user-level installation. Make sure that we are not installing 553 // This is a user-level installation. Make sure that we are not installing
537 // on top of an existing system-level installation. 554 // on top of an existing system-level installation.
538 for (size_t i = 0; i < products.size(); ++i) { 555 for (size_t i = 0; i < products.size(); ++i) {
539 const Product* product = products[i]; 556 const Product* product = products[i];
540 BrowserDistribution* browser_dist = product->distribution(); 557 BrowserDistribution* browser_dist = product->distribution();
558
559 // Skip over the binaries, as it's okay for them to be at both levels
560 // for different products.
561 if (browser_dist->GetType() == BrowserDistribution::CHROME_BINARIES)
562 continue;
563
541 const ProductState* user_level_product_state = 564 const ProductState* user_level_product_state =
542 original_state.GetProductState(false, browser_dist->GetType()); 565 original_state.GetProductState(false, browser_dist->GetType());
543 const ProductState* system_level_product_state = 566 const ProductState* system_level_product_state =
544 original_state.GetProductState(true, browser_dist->GetType()); 567 original_state.GetProductState(true, browser_dist->GetType());
545 568
546 // Allow upgrades to proceed so that out-of-date versions are not left 569 // Allow upgrades to proceed so that out-of-date versions are not left
547 // around. 570 // around.
548 if (user_level_product_state) 571 if (user_level_product_state)
549 continue; 572 continue;
550 573
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
866 installer_state->UpdateStage(installer::PRECONDITIONS); 889 installer_state->UpdateStage(installer::PRECONDITIONS);
867 // The stage provides more fine-grained information than -multifail, so remove 890 // The stage provides more fine-grained information than -multifail, so remove
868 // the -multifail suffix from the Google Update "ap" value. 891 // the -multifail suffix from the Google Update "ap" value.
869 BrowserDistribution::GetSpecificDistribution(installer_state->state_type()) 892 BrowserDistribution::GetSpecificDistribution(installer_state->state_type())
870 ->UpdateInstallStatus(system_install, archive_type, install_status); 893 ->UpdateInstallStatus(system_install, archive_type, install_status);
871 if (CheckPreInstallConditions(original_state, installer_state, 894 if (CheckPreInstallConditions(original_state, installer_state,
872 &install_status)) { 895 &install_status)) {
873 VLOG(1) << "Installing to " << installer_state->target_path().value(); 896 VLOG(1) << "Installing to " << installer_state->target_path().value();
874 install_status = InstallProductsHelper( 897 install_status = InstallProductsHelper(
875 original_state, cmd_line, prefs, *installer_state, &archive_type); 898 original_state, cmd_line, prefs, *installer_state, &archive_type);
899 } else {
900 // CheckPreInstallConditions must set the status on failure.
901 DCHECK_NE(install_status, installer::UNKNOWN_STATUS);
876 } 902 }
877 903
878 const Products& products = installer_state->products(); 904 const Products& products = installer_state->products();
879 905
880 for (size_t i = 0; i < products.size(); ++i) { 906 for (size_t i = 0; i < products.size(); ++i) {
881 const Product* product = products[i]; 907 const Product* product = products[i];
882 product->distribution()->UpdateInstallStatus( 908 product->distribution()->UpdateInstallStatus(
883 system_install, archive_type, install_status); 909 system_install, archive_type, install_status);
884 } 910 }
885 if (installer_state->is_multi_install()) {
grt (UTC plus 2) 2012/07/24 15:02:03 this isn't needed anymore
886 installer_state->multi_package_binaries_distribution()->UpdateInstallStatus(
887 system_install, archive_type, install_status);
888 }
889 911
890 installer_state->UpdateStage(installer::NO_STAGE); 912 installer_state->UpdateStage(installer::NO_STAGE);
891 return install_status; 913 return install_status;
892 } 914 }
893 915
894 installer::InstallStatus UninstallProduct( 916 installer::InstallStatus UninstallProduct(
895 const InstallationState& original_state, 917 const InstallationState& original_state,
896 const InstallerState& installer_state, 918 const InstallerState& installer_state,
897 const CommandLine& cmd_line, 919 const CommandLine& cmd_line,
898 bool remove_all, 920 bool remove_all,
(...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after
1457 const Product* cf_install = 1479 const Product* cf_install =
1458 installer_state.FindProduct(BrowserDistribution::CHROME_FRAME); 1480 installer_state.FindProduct(BrowserDistribution::CHROME_FRAME);
1459 1481
1460 if (cf_install && 1482 if (cf_install &&
1461 !cmd_line.HasSwitch(installer::switches::kForceUninstall)) { 1483 !cmd_line.HasSwitch(installer::switches::kForceUninstall)) {
1462 if (install_status == installer::UNINSTALL_REQUIRES_REBOOT) { 1484 if (install_status == installer::UNINSTALL_REQUIRES_REBOOT) {
1463 ShowRebootDialog(); 1485 ShowRebootDialog();
1464 } else if (is_uninstall) { 1486 } else if (is_uninstall) {
1465 // Only show the message box if Chrome Frame was the only product being 1487 // Only show the message box if Chrome Frame was the only product being
1466 // uninstalled. 1488 // uninstalled.
1467 if (installer_state.products().size() == 1U) { 1489 const Products& products = installer_state.products();
1490 int num_products = 0;
1491 for (size_t i = 0; i < products.size(); ++i) {
grt (UTC plus 2) 2012/07/24 15:02:03 this counting is needed now since the binaries may
1492 if (!products[i]->is_chrome_binaries())
1493 ++num_products;
1494 }
1495 if (num_products == 1U) {
1468 ::MessageBoxW(NULL, 1496 ::MessageBoxW(NULL,
1469 installer::GetLocalizedString( 1497 installer::GetLocalizedString(
1470 IDS_UNINSTALL_COMPLETE_BASE).c_str(), 1498 IDS_UNINSTALL_COMPLETE_BASE).c_str(),
1471 cf_install->distribution()->GetAppShortCutName().c_str(), 1499 cf_install->distribution()->GetAppShortCutName().c_str(),
1472 MB_OK); 1500 MB_OK);
1473 } 1501 }
1474 } 1502 }
1475 } 1503 }
1476 1504
1477 int return_code = 0; 1505 int return_code = 0;
1478 // MSI demands that custom actions always return 0 (ERROR_SUCCESS) or it will 1506 // MSI demands that custom actions always return 0 (ERROR_SUCCESS) or it will
1479 // rollback the action. If we're uninstalling we want to avoid this, so always 1507 // rollback the action. If we're uninstalling we want to avoid this, so always
1480 // report success, squashing any more informative return codes. 1508 // report success, squashing any more informative return codes.
1481 if (!(installer_state.is_msi() && is_uninstall)) 1509 if (!(installer_state.is_msi() && is_uninstall))
1482 // Note that we allow the status installer::UNINSTALL_REQUIRES_REBOOT 1510 // Note that we allow the status installer::UNINSTALL_REQUIRES_REBOOT
1483 // to pass through, since this is only returned on uninstall which is 1511 // to pass through, since this is only returned on uninstall which is
1484 // never invoked directly by Google Update. 1512 // never invoked directly by Google Update.
1485 return_code = InstallUtil::GetInstallReturnCode(install_status); 1513 return_code = InstallUtil::GetInstallReturnCode(install_status);
1486 1514
1487 VLOG(1) << "Installation complete, returning: " << return_code; 1515 VLOG(1) << "Installation complete, returning: " << return_code;
1488 1516
1489 return return_code; 1517 return return_code;
1490 } 1518 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698