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

Side by Side Diff: chrome/installer/launcher_support/chrome_launcher_support.cc

Issue 11054006: Make application shortcuts point to app_host.exe, install App Host during app installation. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years, 2 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
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 "chrome/installer/launcher_support/chrome_launcher_support.h" 5 #include "chrome/installer/launcher_support/chrome_launcher_support.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 #include <tchar.h> 8 #include <tchar.h>
9 #include "base/file_path.h" 9 #include "base/file_path.h"
10 #include "base/file_util.h" 10 #include "base/file_util.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/process_util.h"
13 #include "base/string16.h"
14 #include "base/win/registry.h"
15 #include "base/win/scoped_handle.h"
16
12 #ifndef OFFICIAL_BUILD 17 #ifndef OFFICIAL_BUILD
13 #include "base/path_service.h" 18 #include "base/path_service.h"
14 #endif 19 #endif
15 #include "base/string16.h"
16 #include "base/win/registry.h"
17 20
18 namespace chrome_launcher_support { 21 namespace chrome_launcher_support {
19 22
20 namespace { 23 namespace {
21 24
22 // TODO(huangs) Refactor the constants: http://crbug.com/148538 25 // TODO(huangs) Refactor the constants: http://crbug.com/148538
23 const wchar_t kGoogleRegClientStateKey[] = 26 const wchar_t kGoogleRegClientStateKey[] =
24 L"Software\\Google\\Update\\ClientState\\"; 27 L"Software\\Google\\Update\\ClientState";
28 const wchar_t kGoogleRegClientsKey[] = L"Software\\Google\\Update\\Clients";
29
30 // Copied from binaries_installer_internal.cc
31 const wchar_t kAppHostAppId[] = L"{FDA71E6F-AC4C-4a00-8B70-9958A68906BF}";
25 32
26 // Copied from chrome_appid.cc. 33 // Copied from chrome_appid.cc.
27 const wchar_t kBinariesAppGuid[] = L"{4DC8B4CA-1BDA-483e-B5FA-D3C12E15B62D}"; 34 const wchar_t kBinariesAppGuid[] = L"{4DC8B4CA-1BDA-483e-B5FA-D3C12E15B62D}";
28 35
29 // Copied from google_chrome_distribution.cc. 36 // Copied from google_chrome_distribution.cc.
30 const wchar_t kBrowserAppGuid[] = L"{8A69D345-D564-463c-AFF1-A69D9E530F96}"; 37 const wchar_t kBrowserAppGuid[] = L"{8A69D345-D564-463c-AFF1-A69D9E530F96}";
31 38
39 // Copied from google_update_constants.cc
40 const wchar_t kRegCommandLineField[] = L"CommandLine";
41 const wchar_t kRegCommandsKey[] = L"Commands";
42
32 // Copied from util_constants.cc. 43 // Copied from util_constants.cc.
44 const wchar_t kChromeAppHostExe[] = L"app_host.exe";
45 const wchar_t kChromeExe[] = L"chrome.exe";
46 const wchar_t kCmdQuickEnableApplicationHost[] =
47 L"quick-enable-application-host";
33 const wchar_t kUninstallStringField[] = L"UninstallString"; 48 const wchar_t kUninstallStringField[] = L"UninstallString";
34 const wchar_t kChromeExe[] = L"chrome.exe";
35 49
36 #ifndef OFFICIAL_BUILD 50 #ifndef OFFICIAL_BUILD
37 FilePath GetDevelopmentChrome() { 51 FilePath GetDevelopmentChrome() {
38 FilePath current_directory; 52 FilePath current_directory;
39 if (PathService::Get(base::DIR_EXE, &current_directory)) { 53 if (PathService::Get(base::DIR_EXE, &current_directory)) {
40 FilePath chrome_exe_path(current_directory.Append(kChromeExe)); 54 FilePath chrome_exe_path(current_directory.Append(kChromeExe));
41 if (file_util::PathExists(chrome_exe_path)) 55 if (file_util::PathExists(chrome_exe_path))
42 return chrome_exe_path; 56 return chrome_exe_path;
43 } 57 }
44 return FilePath(); 58 return FilePath();
45 } 59 }
46 #endif 60 #endif
47 61
48 // Reads the path to setup.exe from the value "UninstallString" within the 62 // Reads the path to setup.exe from the value "UninstallString" within the
49 // specified product's "ClientState" registry key. Returns an empty FilePath if 63 // specified product's "ClientState" registry key. Returns an empty FilePath if
50 // an error occurs or the product is not installed at the specified level. 64 // an error occurs or the product is not installed at the specified level.
51 FilePath GetSetupExeFromRegistry(InstallationLevel level, 65 FilePath GetSetupExeFromRegistry(InstallationLevel level,
52 const wchar_t* app_guid) { 66 const wchar_t* app_guid) {
53 HKEY root_key = (level == USER_LEVEL_INSTALLATION) ? 67 HKEY root_key = (level == USER_LEVEL_INSTALLATION) ?
54 HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; 68 HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE;
55 string16 subkey(kGoogleRegClientStateKey); 69 string16 subkey(kGoogleRegClientStateKey);
56 subkey.append(app_guid); 70 subkey.append(1, L'\\').append(app_guid);
57 base::win::RegKey reg_key; 71 base::win::RegKey reg_key;
58 if (reg_key.Open(root_key, subkey.c_str(), 72 if (reg_key.Open(root_key, subkey.c_str(),
59 KEY_QUERY_VALUE) == ERROR_SUCCESS) { 73 KEY_QUERY_VALUE) == ERROR_SUCCESS) {
60 string16 uninstall; 74 string16 uninstall;
61 if (reg_key.ReadValue(kUninstallStringField, &uninstall) == ERROR_SUCCESS) { 75 if (reg_key.ReadValue(kUninstallStringField, &uninstall) == ERROR_SUCCESS) {
62 FilePath setup_exe_path(uninstall); 76 FilePath setup_exe_path(uninstall);
63 if (file_util::PathExists(setup_exe_path)) 77 if (file_util::PathExists(setup_exe_path))
64 return setup_exe_path; 78 return setup_exe_path;
65 } 79 }
66 } 80 }
67 return FilePath(); 81 return FilePath();
68 } 82 }
69 83
84 string16 GetQuickEnableAppHostCommandFromRegistry(InstallationLevel level) {
85 HKEY root_key = (level == USER_LEVEL_INSTALLATION) ?
86 HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE;
87 string16 subkey(kGoogleRegClientsKey);
88 subkey.append(1, L'\\').append(kBinariesAppGuid)
89 .append(1, L'\\').append(kRegCommandsKey)
90 .append(1, L'\\').append(kCmdQuickEnableApplicationHost);
91 base::win::RegKey reg_key;
92 string16 cmd;
93 if (reg_key.Open(root_key, subkey.c_str(),
94 KEY_QUERY_VALUE) == ERROR_SUCCESS) {
95 // If read is unsuccessful, |cmd| remains empty.
96 reg_key.ReadValue(kRegCommandLineField, &cmd);
97 }
98 return cmd;
99 }
100
101 // Returns the path to an installed |exe_file| (e.g. chrome.exe, app_host.exe)
102 // at the specified level, given |setup_exe_path| from Omaha client state.
103 // Returns empty FilePath if none found, or if |setup_exe_path| is empty.
104 FilePath FindExeRelativeToSetupExe(FilePath& setup_exe_path,
105 const wchar_t* exe_file) {
106 if (!setup_exe_path.empty()) {
107 // The uninstall path contains the path to setup.exe, which is two levels
108 // down from |exe_file|. Move up two levels (plus one to drop the file
109 // name) and look for chrome.exe from there.
110 FilePath exe_path(
111 setup_exe_path.DirName().DirName().DirName().Append(exe_file));
112 if (file_util::PathExists(exe_path))
113 return exe_path;
114 // By way of mild future proofing, look up one to see if there's a
115 // |exe_file| in the version directory
116 exe_path = setup_exe_path.DirName().DirName().Append(exe_file);
117 if (file_util::PathExists(exe_path))
118 return exe_path;
119 }
120 return FilePath();
121 }
122
70 } // namespace 123 } // namespace
71 124
72 FilePath GetSetupExeForInstallationLevel(InstallationLevel level) { 125 FilePath GetSetupExeForInstallationLevel(InstallationLevel level) {
73 // Look in the registry for Chrome Binaries first. 126 // Look in the registry for Chrome Binaries first.
74 FilePath setup_exe_path(GetSetupExeFromRegistry(level, kBinariesAppGuid)); 127 FilePath setup_exe_path(GetSetupExeFromRegistry(level, kBinariesAppGuid));
75 // If the above fails, look in the registry for Chrome next. 128 // If the above fails, look in the registry for Chrome next.
76 if (setup_exe_path.empty()) 129 if (setup_exe_path.empty())
77 setup_exe_path = GetSetupExeFromRegistry(level, kBrowserAppGuid); 130 setup_exe_path = GetSetupExeFromRegistry(level, kBrowserAppGuid);
78 // If we fail again, then setup_exe_path would be empty. 131 // If we fail again, then setup_exe_path would be empty.
79 return setup_exe_path; 132 return setup_exe_path;
80 } 133 }
81 134
82 FilePath GetChromePathForInstallationLevel(InstallationLevel level) { 135 FilePath GetChromePathForInstallationLevel(InstallationLevel level) {
83 FilePath setup_exe_path(GetSetupExeForInstallationLevel(level)); 136 FilePath setup_exe_path(GetSetupExeForInstallationLevel(level));
erikwright (departed) 2012/10/03 15:58:35 inline setup_exe_path
huangs 2012/10/03 20:09:47 Done, but now FindExeRelativeToSetupExe() requires
84 if (!setup_exe_path.empty()) { 137 return FindExeRelativeToSetupExe(setup_exe_path, kChromeExe);
85 // The uninstall path contains the path to setup.exe which is two levels 138 }
86 // down from chrome.exe. Move up two levels (plus one to drop the file 139
87 // name) and look for chrome.exe from there. 140 FilePath GetAppHostPathForInstallationLevel(InstallationLevel level) {
88 FilePath chrome_exe_path( 141 FilePath setup_exe_path(GetSetupExeFromRegistry(level, kAppHostAppId));
erikwright (departed) 2012/10/03 15:58:35 inline setup_exe_path
huangs 2012/10/03 20:09:47 Done. Same as above.
89 setup_exe_path.DirName().DirName().DirName().Append(kChromeExe)); 142 return FindExeRelativeToSetupExe(setup_exe_path, kChromeAppHostExe);
90 if (!file_util::PathExists(chrome_exe_path)) {
91 // By way of mild future proofing, look up one to see if there's a
92 // chrome.exe in the version directory
93 chrome_exe_path = chrome_exe_path.DirName().DirName().Append(kChromeExe);
94 }
95 if (file_util::PathExists(chrome_exe_path))
96 return chrome_exe_path;
97 }
98 return FilePath();
99 } 143 }
100 144
101 FilePath GetAnyChromePath() { 145 FilePath GetAnyChromePath() {
102 FilePath chrome_path; 146 FilePath chrome_path;
103 #ifndef OFFICIAL_BUILD 147 #ifndef OFFICIAL_BUILD
104 // For development mode, chrome.exe should be in same dir as the stub. 148 // For development mode, chrome.exe should be in same dir as the stub.
105 chrome_path = GetDevelopmentChrome(); 149 chrome_path = GetDevelopmentChrome();
106 #endif 150 #endif
107 if (chrome_path.empty()) 151 if (chrome_path.empty())
108 chrome_path = GetChromePathForInstallationLevel(SYSTEM_LEVEL_INSTALLATION); 152 chrome_path = GetChromePathForInstallationLevel(SYSTEM_LEVEL_INSTALLATION);
109 if (chrome_path.empty()) 153 if (chrome_path.empty())
110 chrome_path = GetChromePathForInstallationLevel(USER_LEVEL_INSTALLATION); 154 chrome_path = GetChromePathForInstallationLevel(USER_LEVEL_INSTALLATION);
111 return chrome_path; 155 return chrome_path;
112 } 156 }
113 157
158 FilePath GetAnyAppHostPath() {
159 FilePath app_host_path(
160 GetAppHostPathForInstallationLevel(SYSTEM_LEVEL_INSTALLATION));
161 if (app_host_path.empty())
162 app_host_path = GetAppHostPathForInstallationLevel(USER_LEVEL_INSTALLATION);
163 return app_host_path;
164 }
165
166 bool IsAppHostPresent() {
167 FilePath app_host_exe = GetAnyAppHostPath();
168 return !app_host_exe.empty() && file_util::PathExists(app_host_exe);
169 }
170
171 bool LaunchQuickEnableAppHost(base::win::ScopedHandle* process) {
erikwright (departed) 2012/10/03 15:58:35 This doesn't really belong here. Move it into app
huangs 2012/10/03 20:09:47 Done, and removed useless #include's, but now GetQ
172 DCHECK(!process->IsValid());
173 bool success = false;
174 string16 cmd_str(GetQuickEnableAppHostCommandFromRegistry(
175 SYSTEM_LEVEL_INSTALLATION));
176 if (cmd_str.empty()) { // Try user-level if absent from system-level.
177 cmd_str = GetQuickEnableAppHostCommandFromRegistry(
178 USER_LEVEL_INSTALLATION);
179 }
180 if (!cmd_str.empty()) {
181 VLOG(1) << "Quick-enabling application host: " << cmd_str;
182 if (!base::LaunchProcess(cmd_str, base::LaunchOptions(),
183 process->Receive())) {
184 LOG(ERROR) << "Failed to quick-enable application host.";
185 }
186 success = process->IsValid();
187 }
188 return success;
189 }
190
114 } // namespace chrome_launcher_support 191 } // namespace chrome_launcher_support
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698