| 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 #include "chrome/installer/setup/install.h" | 5 #include "chrome/installer/setup/install.h" |
| 6 | 6 |
| 7 #include <windows.h> | 7 #include <windows.h> |
| 8 #include <shlobj.h> | 8 #include <shlobj.h> |
| 9 #include <time.h> | 9 #include <time.h> |
| 10 #include <winuser.h> | 10 #include <winuser.h> |
| 11 | 11 |
| 12 #include <string> | 12 #include <string> |
| 13 | 13 |
| 14 #include "base/command_line.h" | 14 #include "base/command_line.h" |
| 15 #include "base/file_path.h" | 15 #include "base/file_path.h" |
| 16 #include "base/file_util.h" | 16 #include "base/file_util.h" |
| 17 #include "base/logging.h" | 17 #include "base/logging.h" |
| 18 #include "base/memory/scoped_ptr.h" | 18 #include "base/memory/scoped_ptr.h" |
| 19 #include "base/path_service.h" | 19 #include "base/path_service.h" |
| 20 #include "base/string_util.h" | 20 #include "base/string_util.h" |
| 21 #include "base/stringprintf.h" | 21 #include "base/stringprintf.h" |
| 22 #include "base/utf_string_conversions.h" | 22 #include "base/utf_string_conversions.h" |
| 23 #include "base/win/shortcut.h" | 23 #include "base/win/shortcut.h" |
| 24 #include "base/win/windows_version.h" | 24 #include "base/win/windows_version.h" |
| 25 #include "chrome/common/chrome_constants.h" | 25 #include "chrome/common/chrome_constants.h" |
| 26 #include "chrome/common/chrome_switches.h" |
| 26 #include "chrome/installer/setup/install_worker.h" | 27 #include "chrome/installer/setup/install_worker.h" |
| 27 #include "chrome/installer/setup/setup_constants.h" | 28 #include "chrome/installer/setup/setup_constants.h" |
| 28 #include "chrome/installer/util/auto_launch_util.h" | 29 #include "chrome/installer/util/auto_launch_util.h" |
| 29 #include "chrome/installer/util/browser_distribution.h" | 30 #include "chrome/installer/util/browser_distribution.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/delete_after_reboot_helper.h" | 32 #include "chrome/installer/util/delete_after_reboot_helper.h" |
| 32 #include "chrome/installer/util/google_update_constants.h" | 33 #include "chrome/installer/util/google_update_constants.h" |
| 33 #include "chrome/installer/util/helper.h" | 34 #include "chrome/installer/util/helper.h" |
| 34 #include "chrome/installer/util/install_util.h" | 35 #include "chrome/installer/util/install_util.h" |
| 35 #include "chrome/installer/util/master_preferences.h" | 36 #include "chrome/installer/util/master_preferences.h" |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 reg_path.append(installer::kChromeExe); | 126 reg_path.append(installer::kChromeExe); |
| 126 VLOG(1) << "Adding Chrome to Media player list at " << reg_path; | 127 VLOG(1) << "Adding Chrome to Media player list at " << reg_path; |
| 127 scoped_ptr<WorkItem> work_item(WorkItem::CreateCreateRegKeyWorkItem( | 128 scoped_ptr<WorkItem> work_item(WorkItem::CreateCreateRegKeyWorkItem( |
| 128 HKEY_LOCAL_MACHINE, reg_path)); | 129 HKEY_LOCAL_MACHINE, reg_path)); |
| 129 | 130 |
| 130 // if the operation fails we log the error but still continue | 131 // if the operation fails we log the error but still continue |
| 131 if (!work_item.get()->Do()) | 132 if (!work_item.get()->Do()) |
| 132 LOG(ERROR) << "Could not add Chrome to media player inclusion list."; | 133 LOG(ERROR) << "Could not add Chrome to media player inclusion list."; |
| 133 } | 134 } |
| 134 | 135 |
| 135 // Copy master preferences file provided to installer, in the same folder | 136 // Copy master_preferences file provided to installer, in the same folder |
| 136 // as chrome.exe so Chrome first run can find it. This function will be called | 137 // as chrome.exe so Chrome first run can find it. This function will be called |
| 137 // only on the first install of Chrome. | 138 // only on the first install of Chrome. |
| 138 void CopyPreferenceFileForFirstRun(const InstallerState& installer_state, | 139 void CopyPreferenceFileForFirstRun(const InstallerState& installer_state, |
| 139 const FilePath& prefs_source_path) { | 140 const FilePath& prefs_source_path) { |
| 140 FilePath prefs_dest_path(installer_state.target_path().AppendASCII( | 141 FilePath prefs_dest_path(installer_state.target_path().AppendASCII( |
| 141 installer::kDefaultMasterPrefs)); | 142 installer::kDefaultMasterPrefs)); |
| 142 if (!file_util::CopyFile(prefs_source_path, prefs_dest_path)) { | 143 if (!file_util::CopyFile(prefs_source_path, prefs_dest_path)) { |
| 143 VLOG(1) << "Failed to copy master preferences from:" | 144 VLOG(1) << "Failed to copy master preferences from:" |
| 144 << prefs_source_path.value() << " gle: " << ::GetLastError(); | 145 << prefs_source_path.value() << " gle: " << ::GetLastError(); |
| 145 } | 146 } |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 dist->GetUninstallLinkName() + installer::kLnkExt); | 279 dist->GetUninstallLinkName() + installer::kLnkExt); |
| 279 file_util::Delete(uninstall_shortcut_path, false); | 280 file_util::Delete(uninstall_shortcut_path, false); |
| 280 | 281 |
| 281 if (installer_state.system_install()) { | 282 if (installer_state.system_install()) { |
| 282 ShellUtil::RemoveShortcut( | 283 ShellUtil::RemoveShortcut( |
| 283 ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH, dist, chrome_exe.value(), | 284 ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH, dist, chrome_exe.value(), |
| 284 ShellUtil::SYSTEM_LEVEL, NULL); | 285 ShellUtil::SYSTEM_LEVEL, NULL); |
| 285 } | 286 } |
| 286 } | 287 } |
| 287 | 288 |
| 289 // Returns the appropriate shortcut operations for App Launcher, |
| 290 // based on state of installation and master_preferences. |
| 291 installer::InstallShortcutOperation GetAppLauncherShortcutOperation( |
| 292 const InstallationState& original_state, |
| 293 const InstallerState& installer_state) { |
| 294 const installer::ProductState* original_app_host_state = |
| 295 original_state.GetProductState(installer_state.system_install(), |
| 296 BrowserDistribution::CHROME_APP_HOST); |
| 297 bool app_launcher_exists = original_app_host_state && |
| 298 CommandLine(original_app_host_state->uninstall_command()) |
| 299 .HasSwitch(installer::switches::kChromeAppLauncher); |
| 300 if (!app_launcher_exists) |
| 301 return installer::INSTALL_SHORTCUT_CREATE_ALL; |
| 302 |
| 303 return installer::INSTALL_SHORTCUT_REPLACE_EXISTING; |
| 304 } |
| 305 |
| 288 } // end namespace | 306 } // end namespace |
| 289 | 307 |
| 290 namespace installer { | 308 namespace installer { |
| 291 | 309 |
| 292 void EscapeXmlAttributeValueInSingleQuotes(string16* att_value) { | 310 void EscapeXmlAttributeValueInSingleQuotes(string16* att_value) { |
| 293 ReplaceChars(*att_value, L"&", L"&", att_value); | 311 ReplaceChars(*att_value, L"&", L"&", att_value); |
| 294 ReplaceChars(*att_value, L"'", L"'", att_value); | 312 ReplaceChars(*att_value, L"'", L"'", att_value); |
| 295 ReplaceChars(*att_value, L"<", L"<", att_value); | 313 ReplaceChars(*att_value, L"<", L"<", att_value); |
| 296 } | 314 } |
| 297 | 315 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 << " to " << src_path.value(); | 367 << " to " << src_path.value(); |
| 350 return true; | 368 return true; |
| 351 } else { | 369 } else { |
| 352 PLOG(ERROR) << "Error writing " << installer::kVisualElementsManifest | 370 PLOG(ERROR) << "Error writing " << installer::kVisualElementsManifest |
| 353 << " to " << src_path.value(); | 371 << " to " << src_path.value(); |
| 354 return false; | 372 return false; |
| 355 } | 373 } |
| 356 } | 374 } |
| 357 } | 375 } |
| 358 | 376 |
| 377 // TODO(tommi): Change this function to use WorkItemList. |
| 359 void CreateOrUpdateShortcuts( | 378 void CreateOrUpdateShortcuts( |
| 360 const FilePath& chrome_exe, | 379 const FilePath& target, |
| 361 const Product& product, | 380 const Product& product, |
| 362 const MasterPreferences& prefs, | 381 const MasterPreferences& prefs, |
| 363 InstallShortcutLevel install_level, | 382 InstallShortcutLevel install_level, |
| 364 InstallShortcutOperation install_operation) { | 383 InstallShortcutOperation install_operation) { |
| 365 // TODO(tommi): Change this function to use WorkItemList. | |
| 366 DCHECK(product.is_chrome()); | |
| 367 | |
| 368 // Extract shortcut preferences from |prefs|. | 384 // Extract shortcut preferences from |prefs|. |
| 369 bool do_not_create_desktop_shortcut = false; | 385 bool do_not_create_desktop_shortcut = false; |
| 370 bool do_not_create_quick_launch_shortcut = false; | 386 bool do_not_create_quick_launch_shortcut = false; |
| 371 bool alternate_desktop_shortcut = false; | 387 bool alternate_desktop_shortcut = false; |
| 372 prefs.GetBool(master_preferences::kDoNotCreateDesktopShortcut, | 388 prefs.GetBool(master_preferences::kDoNotCreateDesktopShortcut, |
| 373 &do_not_create_desktop_shortcut); | 389 &do_not_create_desktop_shortcut); |
| 374 prefs.GetBool(master_preferences::kDoNotCreateQuickLaunchShortcut, | 390 prefs.GetBool(master_preferences::kDoNotCreateQuickLaunchShortcut, |
| 375 &do_not_create_quick_launch_shortcut); | 391 &do_not_create_quick_launch_shortcut); |
| 376 prefs.GetBool(master_preferences::kAltShortcutText, | 392 prefs.GetBool(master_preferences::kAltShortcutText, |
| 377 &alternate_desktop_shortcut); | 393 &alternate_desktop_shortcut); |
| 378 | 394 |
| 379 BrowserDistribution* dist = product.distribution(); | 395 BrowserDistribution* dist = product.distribution(); |
| 380 // Shortcuts are always installed per-user unless specified. | |
| 381 ShellUtil::ShellChange shortcut_level = (install_level == ALL_USERS ? | |
| 382 ShellUtil::SYSTEM_LEVEL : ShellUtil::CURRENT_USER); | |
| 383 | 396 |
| 384 // The default operation on update is to overwrite shortcuts with the | 397 // The default operation on update is to overwrite shortcuts with the |
| 385 // currently desired properties, but do so only for shortcuts that still | 398 // currently desired properties, but do so only for shortcuts that still |
| 386 // exist. | 399 // exist. |
| 387 ShellUtil::ShortcutOperation shortcut_operation; | 400 ShellUtil::ShortcutOperation shortcut_operation; |
| 388 switch (install_operation) { | 401 switch (install_operation) { |
| 389 case INSTALL_SHORTCUT_CREATE_ALL: | 402 case INSTALL_SHORTCUT_CREATE_ALL: |
| 390 shortcut_operation = ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS; | 403 shortcut_operation = ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS; |
| 391 break; | 404 break; |
| 392 case INSTALL_SHORTCUT_CREATE_EACH_IF_NO_SYSTEM_LEVEL: | 405 case INSTALL_SHORTCUT_CREATE_EACH_IF_NO_SYSTEM_LEVEL: |
| 393 shortcut_operation = ShellUtil::SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL; | 406 shortcut_operation = ShellUtil::SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL; |
| 394 break; | 407 break; |
| 395 default: | 408 default: |
| 396 DCHECK(install_operation == INSTALL_SHORTCUT_REPLACE_EXISTING); | 409 DCHECK(install_operation == INSTALL_SHORTCUT_REPLACE_EXISTING); |
| 397 shortcut_operation = ShellUtil::SHELL_SHORTCUT_REPLACE_EXISTING; | 410 shortcut_operation = ShellUtil::SHELL_SHORTCUT_REPLACE_EXISTING; |
| 398 break; | 411 break; |
| 399 } | 412 } |
| 400 | 413 |
| 414 // Shortcuts are always installed per-user unless specified. |
| 415 ShellUtil::ShellChange shortcut_level = (install_level == ALL_USERS ? |
| 416 ShellUtil::SYSTEM_LEVEL : ShellUtil::CURRENT_USER); |
| 417 |
| 401 // |base_properties|: The basic properties to set on every shortcut installed | 418 // |base_properties|: The basic properties to set on every shortcut installed |
| 402 // (to be refined on a per-shortcut basis). | 419 // (to be refined on a per-shortcut basis). |
| 403 ShellUtil::ShortcutProperties base_properties(shortcut_level); | 420 ShellUtil::ShortcutProperties base_properties(shortcut_level); |
| 404 product.AddDefaultShortcutProperties(chrome_exe, &base_properties); | 421 product.AddDefaultShortcutProperties(target, &base_properties); |
| 405 | 422 |
| 406 if (!do_not_create_desktop_shortcut || | 423 if (!do_not_create_desktop_shortcut || |
| 407 shortcut_operation == ShellUtil::SHELL_SHORTCUT_REPLACE_EXISTING) { | 424 shortcut_operation == ShellUtil::SHELL_SHORTCUT_REPLACE_EXISTING) { |
| 408 ShellUtil::ShortcutProperties desktop_properties(base_properties); | 425 ShellUtil::ShortcutProperties desktop_properties(base_properties); |
| 409 if (alternate_desktop_shortcut) | 426 if (alternate_desktop_shortcut) |
| 410 desktop_properties.set_shortcut_name(dist->GetAlternateApplicationName()); | 427 desktop_properties.set_shortcut_name(dist->GetAlternateApplicationName()); |
| 411 ExecuteAndLogShortcutOperation( | 428 ExecuteAndLogShortcutOperation( |
| 412 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist, desktop_properties, | 429 ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist, desktop_properties, |
| 413 shortcut_operation); | 430 shortcut_operation); |
| 414 | 431 |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 522 | 539 |
| 523 // Update the modifiers on the channel values for the product(s) being | 540 // Update the modifiers on the channel values for the product(s) being |
| 524 // installed and for the binaries in case of multi-install. | 541 // installed and for the binaries in case of multi-install. |
| 525 installer_state.UpdateChannels(); | 542 installer_state.UpdateChannels(); |
| 526 | 543 |
| 527 installer_state.UpdateStage(installer::COPYING_PREFERENCES_FILE); | 544 installer_state.UpdateStage(installer::COPYING_PREFERENCES_FILE); |
| 528 | 545 |
| 529 if (result == FIRST_INSTALL_SUCCESS && !prefs_path.empty()) | 546 if (result == FIRST_INSTALL_SUCCESS && !prefs_path.empty()) |
| 530 CopyPreferenceFileForFirstRun(installer_state, prefs_path); | 547 CopyPreferenceFileForFirstRun(installer_state, prefs_path); |
| 531 | 548 |
| 532 // Currently this only creates shortcuts for Chrome, but for other products | 549 installer_state.UpdateStage(installer::CREATING_SHORTCUTS); |
| 533 // we might want to create shortcuts. | 550 |
| 534 const Product* chrome_install = | 551 const Product* app_launcher_product = |
| 552 installer_state.FindProduct(BrowserDistribution::CHROME_APP_HOST); |
| 553 // Creates shortcuts for App Launcher. |
| 554 if (app_launcher_product && |
| 555 app_launcher_product->HasOption(kOptionAppHostIsLauncher)) { |
| 556 // TODO(huangs): Remove this check once we have system-level App Host. |
| 557 DCHECK(!installer_state.system_install()); |
| 558 const FilePath app_host_exe( |
| 559 installer_state.target_path().Append(kChromeAppHostExe)); |
| 560 InstallShortcutOperation app_launcher_shortcut_operation = |
| 561 GetAppLauncherShortcutOperation(original_state, installer_state); |
| 562 |
| 563 // Always install per-user shortcuts for App Launcher. |
| 564 CreateOrUpdateShortcuts(app_host_exe, *app_launcher_product, prefs, |
| 565 CURRENT_USER, app_launcher_shortcut_operation); |
| 566 } |
| 567 |
| 568 const Product* chrome_product = |
| 535 installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER); | 569 installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER); |
| 536 if (chrome_install) { | 570 // Creates shortcuts for Chrome. |
| 537 installer_state.UpdateStage(installer::CREATING_SHORTCUTS); | 571 if (chrome_product) { |
| 538 | 572 BrowserDistribution* dist = chrome_product->distribution(); |
| 539 BrowserDistribution* dist = chrome_install->distribution(); | |
| 540 const FilePath chrome_exe( | 573 const FilePath chrome_exe( |
| 541 installer_state.target_path().Append(kChromeExe)); | 574 installer_state.target_path().Append(kChromeExe)); |
| 542 CleanupLegacyShortcuts(installer_state, dist, chrome_exe); | 575 CleanupLegacyShortcuts(installer_state, dist, chrome_exe); |
| 543 | 576 |
| 544 InstallShortcutOperation install_operation = | 577 InstallShortcutOperation install_operation = |
| 545 INSTALL_SHORTCUT_REPLACE_EXISTING; | 578 INSTALL_SHORTCUT_REPLACE_EXISTING; |
| 546 if (result == installer::FIRST_INSTALL_SUCCESS || | 579 if (result == installer::FIRST_INSTALL_SUCCESS || |
| 547 result == installer::INSTALL_REPAIRED) { | 580 result == installer::INSTALL_REPAIRED) { |
| 548 install_operation = INSTALL_SHORTCUT_CREATE_ALL; | 581 install_operation = INSTALL_SHORTCUT_CREATE_ALL; |
| 549 } | 582 } |
| 550 | 583 |
| 551 if (installer_state.system_install()) { | 584 if (installer_state.system_install()) { |
| 552 // Update existing all-users shortcuts for legacy installs. | 585 // Update existing all-users shortcuts for legacy installs. |
| 553 CreateOrUpdateShortcuts(chrome_exe, *chrome_install, prefs, ALL_USERS, | 586 CreateOrUpdateShortcuts(chrome_exe, *chrome_product, prefs, ALL_USERS, |
| 554 INSTALL_SHORTCUT_REPLACE_EXISTING); | 587 INSTALL_SHORTCUT_REPLACE_EXISTING); |
| 555 } | 588 } |
| 556 // Always install per-user shortcuts (even on system-level installs where | 589 // Always install per-user shortcuts (even on system-level installs where |
| 557 // we do so for the installing user instead of waiting for Active Setup). | 590 // we do so for the installing user instead of waiting for Active Setup). |
| 558 CreateOrUpdateShortcuts(chrome_exe, *chrome_install, prefs, CURRENT_USER, | 591 CreateOrUpdateShortcuts(chrome_exe, *chrome_product, prefs, CURRENT_USER, |
| 559 install_operation); | 592 install_operation); |
| 593 } |
| 594 |
| 595 if (chrome_product) { |
| 596 // Register Chrome and, if requested, make Chrome the default browser. |
| 597 installer_state.UpdateStage(installer::REGISTERING_CHROME); |
| 560 | 598 |
| 561 bool make_chrome_default = false; | 599 bool make_chrome_default = false; |
| 562 prefs.GetBool(master_preferences::kMakeChromeDefault, | 600 prefs.GetBool(master_preferences::kMakeChromeDefault, |
| 563 &make_chrome_default); | 601 &make_chrome_default); |
| 564 | 602 |
| 565 // If this is not the user's first Chrome install, but they have chosen | 603 // If this is not the user's first Chrome install, but they have chosen |
| 566 // Chrome to become their default browser on the download page, we must | 604 // Chrome to become their default browser on the download page, we must |
| 567 // force it here because the master_preferences file will not get copied | 605 // force it here because the master_preferences file will not get copied |
| 568 // into the build. | 606 // into the build. |
| 569 bool force_chrome_default_for_user = false; | 607 bool force_chrome_default_for_user = false; |
| 570 if (result == NEW_VERSION_UPDATED || | 608 if (result == NEW_VERSION_UPDATED || |
| 571 result == INSTALL_REPAIRED) { | 609 result == INSTALL_REPAIRED) { |
| 572 prefs.GetBool(master_preferences::kMakeChromeDefaultForUser, | 610 prefs.GetBool(master_preferences::kMakeChromeDefaultForUser, |
| 573 &force_chrome_default_for_user); | 611 &force_chrome_default_for_user); |
| 574 } | 612 } |
| 575 | 613 |
| 576 installer_state.UpdateStage(installer::REGISTERING_CHROME); | 614 RegisterChromeOnMachine(installer_state, *chrome_product, |
| 577 | |
| 578 RegisterChromeOnMachine(installer_state, *chrome_install, | |
| 579 make_chrome_default || force_chrome_default_for_user); | 615 make_chrome_default || force_chrome_default_for_user); |
| 580 | 616 |
| 617 // Configure auto-launch. |
| 581 if (result == FIRST_INSTALL_SUCCESS) { | 618 if (result == FIRST_INSTALL_SUCCESS) { |
| 582 installer_state.UpdateStage(installer::CONFIGURE_AUTO_LAUNCH); | 619 installer_state.UpdateStage(installer::CONFIGURE_AUTO_LAUNCH); |
| 583 | 620 |
| 584 // Add auto-launch key if specified in master preferences. | 621 // Add auto-launch key if specified in master_preferences. |
| 585 bool auto_launch_chrome = false; | 622 bool auto_launch_chrome = false; |
| 586 prefs.GetBool( | 623 prefs.GetBool( |
| 587 installer::master_preferences::kAutoLaunchChrome, | 624 installer::master_preferences::kAutoLaunchChrome, |
| 588 &auto_launch_chrome); | 625 &auto_launch_chrome); |
| 589 if (auto_launch_chrome) { | 626 if (auto_launch_chrome) { |
| 590 auto_launch_util::EnableForegroundStartAtLogin( | 627 auto_launch_util::EnableForegroundStartAtLogin( |
| 591 ASCIIToUTF16(chrome::kInitialProfile), | 628 ASCIIToUTF16(chrome::kInitialProfile), |
| 592 installer_state.target_path()); | 629 installer_state.target_path()); |
| 593 } | 630 } |
| 594 } | 631 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 650 INSTALL_SHORTCUT_CREATE_EACH_IF_NO_SYSTEM_LEVEL); | 687 INSTALL_SHORTCUT_CREATE_EACH_IF_NO_SYSTEM_LEVEL); |
| 651 | 688 |
| 652 // Read master_preferences copied beside chrome.exe at install. | 689 // Read master_preferences copied beside chrome.exe at install. |
| 653 MasterPreferences prefs(installation_root.AppendASCII(kDefaultMasterPrefs)); | 690 MasterPreferences prefs(installation_root.AppendASCII(kDefaultMasterPrefs)); |
| 654 FilePath chrome_exe(installation_root.Append(kChromeExe)); | 691 FilePath chrome_exe(installation_root.Append(kChromeExe)); |
| 655 CreateOrUpdateShortcuts( | 692 CreateOrUpdateShortcuts( |
| 656 chrome_exe, chrome, prefs, CURRENT_USER, install_operation); | 693 chrome_exe, chrome, prefs, CURRENT_USER, install_operation); |
| 657 } | 694 } |
| 658 | 695 |
| 659 } // namespace installer | 696 } // namespace installer |
| OLD | NEW |