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

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

Issue 1525042: Additional changes to support Chrome / CF installation wrapped in an MSI:... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 7 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
« no previous file with comments | « no previous file | chrome/installer/setup/setup_main.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 <shlobj.h> 5 #include <shlobj.h>
6 #include <time.h> 6 #include <time.h>
7 7
8 #include "chrome/installer/setup/install.h" 8 #include "chrome/installer/setup/install.h"
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 uninstall_cmd_line->append(installer_util::switches::kDeleteProfile); 92 uninstall_cmd_line->append(installer_util::switches::kDeleteProfile);
93 uninstall_cmd_line->append(L" --"); 93 uninstall_cmd_line->append(L" --");
94 uninstall_cmd_line->append(installer_util::switches::kChromeFrame); 94 uninstall_cmd_line->append(installer_util::switches::kChromeFrame);
95 } 95 }
96 96
97 if (InstallUtil::IsChromeSxSProcess()) { 97 if (InstallUtil::IsChromeSxSProcess()) {
98 uninstall_cmd_line->append(L" --"); 98 uninstall_cmd_line->append(L" --");
99 uninstall_cmd_line->append(installer_util::switches::kChromeSxS); 99 uninstall_cmd_line->append(installer_util::switches::kChromeSxS);
100 } 100 }
101 101
102 if (InstallUtil::IsMSIProcess()) { 102 if (InstallUtil::IsMSIProcess(is_system)) {
103 uninstall_cmd_line->append(L" --"); 103 uninstall_cmd_line->append(L" --");
104 uninstall_cmd_line->append(installer_util::switches::kMsi); 104 uninstall_cmd_line->append(installer_util::switches::kMsi);
105 } 105 }
106 106
107 // Propagate the verbose logging switch to uninstalls too. 107 // Propagate the verbose logging switch to uninstalls too.
108 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 108 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
109 if (command_line.HasSwitch(installer_util::switches::kVerboseLogging)) { 109 if (command_line.HasSwitch(installer_util::switches::kVerboseLogging)) {
110 uninstall_cmd_line->append(L" --"); 110 uninstall_cmd_line->append(L" --");
111 uninstall_cmd_line->append(installer_util::switches::kVerboseLogging); 111 uninstall_cmd_line->append(installer_util::switches::kVerboseLogging);
112 } 112 }
113 113
114 if (is_system) { 114 if (is_system) {
115 uninstall_cmd_line->append(L" --"); 115 uninstall_cmd_line->append(L" --");
116 uninstall_cmd_line->append(installer_util::switches::kSystemLevel); 116 uninstall_cmd_line->append(installer_util::switches::kSystemLevel);
117 } 117 }
118 } 118 }
119 119
120 // This method adds work items to create (or update) Chrome uninstall entry in 120 // This method adds work items to create (or update) Chrome uninstall entry in
121 // either the Control Panel->Add/Remove Programs list or in the Omaha client 121 // either the Control Panel->Add/Remove Programs list or in the Omaha client
122 // state key if running under an MSI installer. 122 // state key if running under an MSI installer.
123 void AddUninstallShortcutWorkItems(HKEY reg_root, 123 void AddUninstallShortcutWorkItems(HKEY reg_root,
124 const std::wstring& exe_path, 124 const std::wstring& exe_path,
125 const std::wstring& install_path, 125 const std::wstring& install_path,
126 const std::wstring& product_name, 126 const std::wstring& product_name,
127 const std::wstring& new_version, 127 const std::wstring& new_version,
128 WorkItemList* install_list) { 128 WorkItemList* install_list) {
129 std::wstring uninstall_cmd(L"\"");
130 uninstall_cmd.append(installer::GetInstallerPathUnderChrome(install_path,
131 new_version));
132 file_util::AppendToPath(&uninstall_cmd,
133 file_util::GetFilenameFromPath(exe_path));
134 uninstall_cmd.append(L"\"");
135
136 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); 129 BrowserDistribution* dist = BrowserDistribution::GetDistribution();
137 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 130 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
138 131
139
140 // When we are installed via an MSI, we need to store our uninstall strings 132 // When we are installed via an MSI, we need to store our uninstall strings
141 // in the Google Update client state key. We do this even for non-MSI 133 // in the Google Update client state key. We do this even for non-MSI
142 // managed installs to avoid breaking the edge case whereby an MSI-managed 134 // managed installs to avoid breaking the edge case whereby an MSI-managed
143 // install is updated by a non-msi installer (which would confuse the MSI 135 // install is updated by a non-msi installer (which would confuse the MSI
144 // machinery if these strings were not also updated). 136 // machinery if these strings were not also updated).
137 // Do not quote the command line for the MSI invocation.
138 std::wstring uninstall_cmd(
139 installer::GetInstallerPathUnderChrome(install_path, new_version));
140 file_util::AppendToPath(&uninstall_cmd,
141 file_util::GetFilenameFromPath(exe_path));
145 std::wstring uninstall_arguments; 142 std::wstring uninstall_arguments;
146 AppendUninstallCommandLineFlags(&uninstall_arguments, 143 AppendUninstallCommandLineFlags(&uninstall_arguments,
147 reg_root == HKEY_LOCAL_MACHINE); 144 reg_root == HKEY_LOCAL_MACHINE);
145
148 std::wstring update_state_key = dist->GetStateKey(); 146 std::wstring update_state_key = dist->GetStateKey();
149 install_list->AddCreateRegKeyWorkItem(reg_root, update_state_key); 147 install_list->AddCreateRegKeyWorkItem(reg_root, update_state_key);
150 install_list->AddSetRegValueWorkItem(reg_root, update_state_key, 148 install_list->AddSetRegValueWorkItem(reg_root, update_state_key,
151 installer_util::kUninstallStringField, uninstall_cmd, true); 149 installer_util::kUninstallStringField, uninstall_cmd, true);
152 install_list->AddSetRegValueWorkItem(reg_root, update_state_key, 150 install_list->AddSetRegValueWorkItem(reg_root, update_state_key,
153 installer_util::kUninstallArgumentsField, uninstall_arguments, true); 151 installer_util::kUninstallArgumentsField, uninstall_arguments, true);
154 152
155 // MSI installations will manage their own uninstall shortcuts. 153 // MSI installations will manage their own uninstall shortcuts.
156 if (!InstallUtil::IsMSIProcess()) { 154 if (!InstallUtil::IsMSIProcess(reg_root == HKEY_LOCAL_MACHINE)) {
157 AppendUninstallCommandLineFlags(&uninstall_cmd, 155 // We need to quote the command line for the Add/Remove Programs dialog.
156 std::wstring quoted_uninstall_cmd(L"\"");
157 quoted_uninstall_cmd += uninstall_cmd;
158 quoted_uninstall_cmd += L"\"";
159
160 AppendUninstallCommandLineFlags(&quoted_uninstall_cmd,
158 reg_root == HKEY_LOCAL_MACHINE); 161 reg_root == HKEY_LOCAL_MACHINE);
159 std::wstring uninstall_reg = dist->GetUninstallRegPath(); 162 std::wstring uninstall_reg = dist->GetUninstallRegPath();
160 install_list->AddCreateRegKeyWorkItem(reg_root, uninstall_reg); 163 install_list->AddCreateRegKeyWorkItem(reg_root, uninstall_reg);
161 install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, 164 install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg,
162 installer_util::kUninstallDisplayNameField, product_name, true); 165 installer_util::kUninstallDisplayNameField, product_name, true);
163 install_list->AddSetRegValueWorkItem(reg_root, 166 install_list->AddSetRegValueWorkItem(reg_root,
164 uninstall_reg, 167 uninstall_reg,
165 installer_util::kUninstallStringField, 168 installer_util::kUninstallStringField,
166 uninstall_cmd, true); 169 quoted_uninstall_cmd,
170 true);
167 install_list->AddSetRegValueWorkItem(reg_root, 171 install_list->AddSetRegValueWorkItem(reg_root,
168 uninstall_reg, 172 uninstall_reg,
169 L"InstallLocation", 173 L"InstallLocation",
170 install_path, 174 install_path,
171 true); 175 true);
172 176
173 // DisplayIcon, NoModify and NoRepair 177 // DisplayIcon, NoModify and NoRepair
174 std::wstring chrome_icon = AppendPath(install_path, 178 std::wstring chrome_icon = AppendPath(install_path,
175 installer_util::kChromeExe); 179 installer_util::kChromeExe);
176 ShellUtil::GetChromeIcon(chrome_icon); 180 ShellUtil::GetChromeIcon(chrome_icon);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 chrome_link.value(), 279 chrome_link.value(),
276 product_desc, true); 280 product_desc, true);
277 } else if (file_util::PathExists(chrome_link)) { 281 } else if (file_util::PathExists(chrome_link)) {
278 LOG(INFO) << "Updating shortcut at " << chrome_link.value() 282 LOG(INFO) << "Updating shortcut at " << chrome_link.value()
279 << " to point to " << chrome_exe; 283 << " to point to " << chrome_exe;
280 ret = ret && ShellUtil::UpdateChromeShortcut(chrome_exe, 284 ret = ret && ShellUtil::UpdateChromeShortcut(chrome_exe,
281 chrome_link.value(), 285 chrome_link.value(),
282 product_desc, false); 286 product_desc, false);
283 } 287 }
284 288
285 // Create/update uninstall link 289 // Create/update uninstall link if we are not an MSI install. MSI
286 FilePath uninstall_link(shortcut_path); // Uninstall Chrome link 290 // installations are, for the time being, managed only through the
287 uninstall_link = uninstall_link.Append( 291 // Add/Remove Programs dialog.
288 dist->GetUninstallLinkName() + L".lnk"); 292 // TODO(robertshield): We could add a shortcut to msiexec /X {GUID} here.
289 if ((install_status == installer_util::FIRST_INSTALL_SUCCESS) || 293 if (!InstallUtil::IsMSIProcess(system_install)) {
290 (install_status == installer_util::INSTALL_REPAIRED) || 294 FilePath uninstall_link(shortcut_path); // Uninstall Chrome link
291 (file_util::PathExists(uninstall_link))) { 295 uninstall_link = uninstall_link.Append(
292 if (!file_util::PathExists(shortcut_path)) 296 dist->GetUninstallLinkName() + L".lnk");
293 file_util::CreateDirectoryW(shortcut_path); 297 if ((install_status == installer_util::FIRST_INSTALL_SUCCESS) ||
294 std::wstring setup_exe(installer::GetInstallerPathUnderChrome(install_path, 298 (install_status == installer_util::INSTALL_REPAIRED) ||
295 new_version)); 299 (file_util::PathExists(uninstall_link))) {
296 file_util::AppendToPath(&setup_exe, 300 if (!file_util::PathExists(shortcut_path))
297 file_util::GetFilenameFromPath(exe_path)); 301 file_util::CreateDirectoryW(shortcut_path);
302 std::wstring setup_exe(installer::GetInstallerPathUnderChrome(
303 install_path, new_version));
304 file_util::AppendToPath(&setup_exe,
305 file_util::GetFilenameFromPath(exe_path));
298 306
299 std::wstring arguments; 307 std::wstring arguments;
300 AppendUninstallCommandLineFlags(&arguments, system_install); 308 AppendUninstallCommandLineFlags(&arguments, system_install);
301 309 LOG(INFO) << "Creating/updating uninstall link at "
302 LOG(INFO) << "Creating/updating uninstall link at " 310 << uninstall_link.value();
303 << uninstall_link.value(); 311 ret = ret && file_util::CreateShortcutLink(setup_exe.c_str(),
304 ret = ret && file_util::CreateShortcutLink(setup_exe.c_str(), 312 uninstall_link.value().c_str(),
305 uninstall_link.value().c_str(), 313 NULL,
306 NULL, 314 arguments.c_str(),
307 arguments.c_str(), 315 NULL,
308 NULL, setup_exe.c_str(), 0, 316 setup_exe.c_str(),
309 NULL); 317 0,
318 NULL);
319 }
310 } 320 }
311 321
312 // Update Desktop and Quick Launch shortcuts. If --create-new-shortcuts 322 // Update Desktop and Quick Launch shortcuts. If --create-new-shortcuts
313 // is specified we want to create them, otherwise we update them only if 323 // is specified we want to create them, otherwise we update them only if
314 // they exist. 324 // they exist.
315 if (system_install) { 325 if (system_install) {
316 ret = ret && ShellUtil::CreateChromeDesktopShortcut(chrome_exe, 326 ret = ret && ShellUtil::CreateChromeDesktopShortcut(chrome_exe,
317 product_desc, ShellUtil::SYSTEM_LEVEL, alt_shortcut, 327 product_desc, ShellUtil::SYSTEM_LEVEL, alt_shortcut,
318 create_all_shortcut); 328 create_all_shortcut);
319 ret = ret && ShellUtil::CreateChromeQuickLaunchShortcut(chrome_exe, 329 ret = ret && ShellUtil::CreateChromeQuickLaunchShortcut(chrome_exe,
320 ShellUtil::CURRENT_USER | ShellUtil::SYSTEM_LEVEL, create_all_shortcut); 330 ShellUtil::CURRENT_USER | ShellUtil::SYSTEM_LEVEL, create_all_shortcut);
321 } else { 331 } else {
322 ret = ret && ShellUtil::CreateChromeDesktopShortcut(chrome_exe, 332 ret = ret && ShellUtil::CreateChromeDesktopShortcut(chrome_exe,
323 product_desc, ShellUtil::CURRENT_USER, alt_shortcut, 333 product_desc, ShellUtil::CURRENT_USER, alt_shortcut,
324 create_all_shortcut); 334 create_all_shortcut);
325 ret = ret && ShellUtil::CreateChromeQuickLaunchShortcut(chrome_exe, 335 ret = ret && ShellUtil::CreateChromeQuickLaunchShortcut(chrome_exe,
326 ShellUtil::CURRENT_USER, create_all_shortcut); 336 ShellUtil::CURRENT_USER, create_all_shortcut);
327 } 337 }
328 338
329 return ret; 339 return ret;
330 } 340 }
331 341
332 // After a successful copying of all the files, this function is called to 342 // After a successful copying of all the files, this function is called to
333 // do a few post install tasks: 343 // do a few post install tasks:
334 // - Handle the case of in-use-update by updating "opv" key or deleting it if 344 // - Handle the case of in-use-update by updating "opv" key or deleting it if
335 // not required. 345 // not required.
336 // - Register any new dlls and unregister old dlls. 346 // - Register any new dlls and unregister old dlls.
347 // - If this is an MSI install, ensures that the MSI marker is set, and sets
348 // it if not.
337 // If these operations are successful, the function returns true, otherwise 349 // If these operations are successful, the function returns true, otherwise
338 // false. 350 // false.
339 bool DoPostInstallTasks(HKEY reg_root, 351 bool DoPostInstallTasks(HKEY reg_root,
340 const std::wstring& exe_path, 352 const std::wstring& exe_path,
341 const std::wstring& install_path, 353 const std::wstring& install_path,
342 const std::wstring& new_chrome_exe, 354 const std::wstring& new_chrome_exe,
343 const std::wstring& current_version, 355 const std::wstring& current_version,
344 const installer::Version& new_version) { 356 const installer::Version& new_version) {
345 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); 357 BrowserDistribution* dist = BrowserDistribution::GetDistribution();
346 std::wstring version_key = dist->GetVersionKey(); 358 std::wstring version_key = dist->GetVersionKey();
347 359
360 bool is_system_install = (reg_root == HKEY_LOCAL_MACHINE);
361
348 if (file_util::PathExists(FilePath::FromWStringHack(new_chrome_exe))) { 362 if (file_util::PathExists(FilePath::FromWStringHack(new_chrome_exe))) {
349 // Looks like this was in use update. So make sure we update the 'opv' key 363 // Looks like this was in use update. So make sure we update the 'opv' key
350 // with the current version that is active and 'cmd' key with the rename 364 // with the current version that is active and 'cmd' key with the rename
351 // command to run. 365 // command to run.
352 if (current_version.empty()) { 366 if (current_version.empty()) {
353 LOG(ERROR) << "New chrome.exe exists but current version is empty!"; 367 LOG(ERROR) << "New chrome.exe exists but current version is empty!";
354 return false; 368 return false;
355 } 369 }
356 scoped_ptr<WorkItemList> inuse_list(WorkItem::CreateWorkItemList()); 370 scoped_ptr<WorkItemList> inuse_list(WorkItem::CreateWorkItemList());
357 inuse_list->AddSetRegValueWorkItem(reg_root, 371 inuse_list->AddSetRegValueWorkItem(reg_root,
358 version_key, 372 version_key,
359 google_update::kRegOldVersionField, 373 google_update::kRegOldVersionField,
360 current_version.c_str(), 374 current_version.c_str(),
361 true); 375 true);
362 376
363 std::wstring rename_cmd(installer::GetInstallerPathUnderChrome( 377 std::wstring rename_cmd(installer::GetInstallerPathUnderChrome(
364 install_path, new_version.GetString())); 378 install_path, new_version.GetString()));
365 file_util::AppendToPath(&rename_cmd, 379 file_util::AppendToPath(&rename_cmd,
366 file_util::GetFilenameFromPath(exe_path)); 380 file_util::GetFilenameFromPath(exe_path));
367 rename_cmd = L"\"" + rename_cmd + 381 rename_cmd = L"\"" + rename_cmd +
368 L"\" --" + installer_util::switches::kRenameChromeExe; 382 L"\" --" + installer_util::switches::kRenameChromeExe;
369 if (reg_root == HKEY_LOCAL_MACHINE) 383 if (is_system_install)
370 rename_cmd = rename_cmd + L" --" + installer_util::switches::kSystemLevel; 384 rename_cmd = rename_cmd + L" --" + installer_util::switches::kSystemLevel;
371 385
372 if (InstallUtil::IsChromeFrameProcess()) { 386 if (InstallUtil::IsChromeFrameProcess()) {
373 rename_cmd += L" --"; 387 rename_cmd += L" --";
374 rename_cmd += installer_util::switches::kChromeFrame; 388 rename_cmd += installer_util::switches::kChromeFrame;
375 } 389 }
376 390
377 if (InstallUtil::IsChromeSxSProcess()) { 391 if (InstallUtil::IsChromeSxSProcess()) {
378 rename_cmd += L" --"; 392 rename_cmd += L" --";
379 rename_cmd += installer_util::switches::kChromeSxS; 393 rename_cmd += installer_util::switches::kChromeSxS;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 if (InstallUtil::BuildDLLRegistrationList(dll_path, kDllsToRegister, 448 if (InstallUtil::BuildDLLRegistrationList(dll_path, kDllsToRegister,
435 kNumDllsToRegister, true, 449 kNumDllsToRegister, true,
436 dll_list.get())) { 450 dll_list.get())) {
437 if (!dll_list->Do()) { 451 if (!dll_list->Do()) {
438 dll_list->Rollback(); 452 dll_list->Rollback();
439 return false; 453 return false;
440 } 454 }
441 } 455 }
442 } 456 }
443 457
458 // If we're told that we're an MSI install, make sure to set the marker
459 // in the client state key so that future updates do the right thing.
460 if (InstallUtil::IsMSIProcess(is_system_install)) {
461 if (!InstallUtil::SetMSIMarker(is_system_install, true))
462 return false;
463 }
464
444 return true; 465 return true;
445 } 466 }
446 467
447 // This method tells if we are running on 64 bit platform so that we can copy 468 // This method tells if we are running on 64 bit platform so that we can copy
448 // one extra exe. If the API call to determine 64 bit fails, we play it safe 469 // one extra exe. If the API call to determine 64 bit fails, we play it safe
449 // and return true anyway so that the executable can be copied. 470 // and return true anyway so that the executable can be copied.
450 bool Is64bit() { 471 bool Is64bit() {
451 typedef BOOL (WINAPI *WOW_FUNC)(HANDLE, PBOOL); 472 typedef BOOL (WINAPI *WOW_FUNC)(HANDLE, PBOOL);
452 BOOL is64 = FALSE; 473 BOOL is64 = FALSE;
453 474
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
714 } 735 }
715 736
716 std::wstring latest_version_to_keep(new_version.GetString()); 737 std::wstring latest_version_to_keep(new_version.GetString());
717 if (!current_version.empty()) 738 if (!current_version.empty())
718 latest_version_to_keep.assign(current_version); 739 latest_version_to_keep.assign(current_version);
719 RemoveOldVersionDirs(install_path, latest_version_to_keep); 740 RemoveOldVersionDirs(install_path, latest_version_to_keep);
720 } 741 }
721 742
722 return result; 743 return result;
723 } 744 }
OLDNEW
« no previous file with comments | « no previous file | chrome/installer/setup/setup_main.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698