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

Unified Diff: chrome/installer/util/shell_util.cc

Issue 10823178: Register Chrome in Open With for File Associations at install on Windows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: naming and comments Created 8 years, 4 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 side-by-side diff with in-line comments
Download patch
« chrome/installer/setup/uninstall.cc ('K') | « chrome/installer/util/shell_util.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/installer/util/shell_util.cc
diff --git a/chrome/installer/util/shell_util.cc b/chrome/installer/util/shell_util.cc
index ad8ace3261ac290daa3197b91e34a8e213a3af77..fc31317e202ab411af0b66670145daca39e5b057 100644
--- a/chrome/installer/util/shell_util.cc
+++ b/chrome/installer/util/shell_util.cc
@@ -204,10 +204,10 @@ class RegistryEntry {
}
// This method returns a list of all the registry entries that
- // are needed to register Chromium ProgIds.
+ // are needed to register this installation's ProgId and AppId.
// These entries should be registered in HKCU for user-level installs and in
// HKLM for system-level installs.
- static bool GetProgIdEntries(BrowserDistribution* dist,
+ static void GetProgIdEntries(BrowserDistribution* dist,
const string16& chrome_exe,
const string16& suffix,
std::list<RegistryEntry*>* entries) {
@@ -302,31 +302,31 @@ class RegistryEntry {
chrome_application, ShellUtil::kRegApplicationCompany,
dist->GetPublisherName()));
}
-
- return true;
}
// This method returns a list of the registry entries needed to declare a
// capability of handling a protocol on Windows.
- static bool GetProtocolCapabilityEntries(BrowserDistribution* dist,
+ static void GetProtocolCapabilityEntries(BrowserDistribution* dist,
const string16& suffix,
const string16& protocol,
std::list<RegistryEntry*>* entries) {
entries->push_front(new RegistryEntry(
GetCapabilitiesKey(dist, suffix).append(L"\\URLAssociations"),
protocol, GetBrowserProgId(suffix)));
- return true;
}
- // This method returns a list of all the registry entries required to fully
- // integrate Chrome with Windows (i.e. StartMenuInternet, Default Programs,
- // AppPaths, etc.). This entries need to be registered in HKLM prior to Win8.
- static bool GetShellIntegrationEntries(BrowserDistribution* dist,
+ // This method returns a list of the registry entries required to register
+ // this installation in "RegisteredApplications" on Windows (to appear in
+ // Default Programs, StartMenuInternet, etc.).
+ // These entries need to be registered in HKLM prior to Win8.
+ // If |suffix| is not empty, these entries are guaranteed to be unique on this
+ // machine.
+ static void GetShellIntegrationEntries(BrowserDistribution* dist,
const string16& chrome_exe,
const string16& suffix,
std::list<RegistryEntry*>* entries) {
- string16 icon_path = ShellUtil::GetChromeIcon(dist, chrome_exe);
- string16 quoted_exe_path = L"\"" + chrome_exe + L"\"";
+ const string16 icon_path(ShellUtil::GetChromeIcon(dist, chrome_exe));
+ const string16 quoted_exe_path(L"\"" + chrome_exe + L"\"");
// Register for the Start Menu "Internet" link (pre-Win7).
const string16 start_menu_entry(GetBrowserClientKey(dist, suffix));
@@ -355,9 +355,9 @@ class RegistryEntry {
entries->push_front(new RegistryEntry(install_info, L"IconsVisible", 1));
// Register with Default Programs.
- string16 reg_app_name(dist->GetBaseAppName().append(suffix));
+ const string16 reg_app_name(dist->GetBaseAppName().append(suffix));
// Tell Windows where to find Chrome's Default Programs info.
- string16 capabilities(GetCapabilitiesKey(dist, suffix));
+ const string16 capabilities(GetCapabilitiesKey(dist, suffix));
entries->push_front(new RegistryEntry(ShellUtil::kRegRegisteredApplications,
reg_app_name, capabilities));
// Write out Chrome's Default Programs info.
@@ -375,7 +375,7 @@ class RegistryEntry {
entries->push_front(new RegistryEntry(capabilities + L"\\Startmenu",
L"StartMenuInternet", reg_app_name));
- string16 html_prog_id(GetBrowserProgId(suffix));
+ const string16 html_prog_id(GetBrowserProgId(suffix));
for (int i = 0; ShellUtil::kFileAssociations[i] != NULL; i++) {
entries->push_front(new RegistryEntry(
capabilities + L"\\FileAssociations",
@@ -387,9 +387,17 @@ class RegistryEntry {
capabilities + L"\\URLAssociations",
ShellUtil::kPotentialProtocolAssociations[i], html_prog_id));
}
+ }
- // Application Registration.
- FilePath chrome_path(chrome_exe);
+ // This method returns a list of the registry entries required for this
+ // installation to be registered in the Windows shell.
+ // In particular: App Paths and File Associations.
robertshield 2012/08/05 15:01:12 Please add links to http://msdn.microsoft.com/en-u
gab 2012/08/06 19:39:27 Done.
+ // These entries should be registered in HKCU for user-level installs and in
+ // HKLM for system-level installs.
+ static void GetAppRegistrationEntries(const string16& chrome_exe,
+ const string16& suffix,
+ std::list<RegistryEntry*>* entries) {
robertshield 2012/08/05 15:01:12 any reason not to use base::ScopedVector here? it
gab 2012/08/06 19:39:27 shell_util has been using std::list forever, but I
+ const FilePath chrome_path(chrome_exe);
string16 app_path_key(ShellUtil::kAppPathsRegistryKey);
app_path_key.push_back(FilePath::kSeparators[0]);
app_path_key.append(chrome_path.BaseName().value());
@@ -397,13 +405,20 @@ class RegistryEntry {
entries->push_front(new RegistryEntry(app_path_key,
ShellUtil::kAppPathsRegistryPathName, chrome_path.DirName().value()));
- // TODO: add chrome to open with list (Bug 16726).
- return true;
+ const string16 html_prog_id(GetBrowserProgId(suffix));
+ for (int i = 0; ShellUtil::kFileAssociations[i] != NULL; i++) {
+ string16 key(ShellUtil::kRegClasses);
+ key.push_back(FilePath::kSeparators[0]);
+ key.append(ShellUtil::kFileAssociations[i]);
+ key.push_back(FilePath::kSeparators[0]);
+ key.append(ShellUtil::kRegOpenWithProgids);
+ entries->push_front(new RegistryEntry(key, html_prog_id, string16()));
+ }
}
// This method returns a list of all the user level registry entries that
// are needed to make Chromium the default handler for a protocol.
- static bool GetUserProtocolEntries(const string16& protocol,
+ static void GetUserProtocolEntries(const string16& protocol,
const string16& chrome_icon,
const string16& chrome_open,
std::list<RegistryEntry*>* entries) {
@@ -433,16 +448,17 @@ class RegistryEntry {
// <root hkey>\Software\Classes\<protocol>\shell\@
string16 protocol_shell_key = url_key + ShellUtil::kRegShellPath;
entries->push_front(new RegistryEntry(protocol_shell_key, L"open"));
-
- return true;
}
// This method returns a list of all the user level registry entries that
// are needed to make Chromium default browser.
- static bool GetUserEntries(BrowserDistribution* dist,
- const string16& chrome_exe,
- const string16& suffix,
- std::list<RegistryEntry*>* entries) {
+ // Some of these entries are irrelevant in recent versions of Windows, but
+ // we register them anyways as some legacy apps are hardcoded to lookup those
+ // values.
+ static void GetDefaultBrowserUserEntries(BrowserDistribution* dist,
+ const string16& chrome_exe,
+ const string16& suffix,
+ std::list<RegistryEntry*>* entries) {
robertshield 2012/08/05 15:01:12 same comment about base::ScopedVector
gab 2012/08/06 19:39:27 Done.
// File extension associations.
string16 html_prog_id(GetBrowserProgId(suffix));
for (int i = 0; ShellUtil::kFileAssociations[i] != NULL; i++) {
@@ -464,7 +480,6 @@ class RegistryEntry {
string16 start_menu(ShellUtil::kRegStartMenuInternet);
string16 app_name = dist->GetBaseAppName() + suffix;
entries->push_front(new RegistryEntry(start_menu, app_name));
- return true;
}
// Generate work_item tasks required to create current registry entry and
@@ -604,8 +619,8 @@ bool IsChromeRegistered(BrowserDistribution* dist,
std::list<RegistryEntry*> entries;
STLElementDeleter<std::list<RegistryEntry*> > entries_deleter(&entries);
RegistryEntry::GetProgIdEntries(dist, chrome_exe, suffix, &entries);
- RegistryEntry::GetShellIntegrationEntries(
- dist, chrome_exe, suffix, &entries);
+ RegistryEntry::GetShellIntegrationEntries(dist, chrome_exe, suffix, &entries);
+ RegistryEntry::GetAppRegistrationEntries(chrome_exe, suffix, &entries);
return AreEntriesRegistered(entries, RegistryEntry::LOOK_IN_HKCU_THEN_HKLM);
}
@@ -868,6 +883,35 @@ HKEY DetermineShellIntegrationRoot(bool is_per_user) {
HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE;
}
+// Associates Chrome with supported protocols and file associations. This should
+// not be required on Vista+ but since some applications still read
+// Software\Classes\http key directly, we have to do this on Vista+ as well.
+bool RegisterChromeAsDefaultForXP(BrowserDistribution* dist,
+ int shell_change,
+ const string16& chrome_exe) {
+ bool ret = true;
+ std::list<RegistryEntry*> entries;
+ STLElementDeleter<std::list<RegistryEntry*> > entries_deleter(&entries);
+ RegistryEntry::GetDefaultBrowserUserEntries(
+ dist, chrome_exe,
+ ShellUtil::GetCurrentInstallationSuffix(dist, chrome_exe), &entries);
+ // Change the default browser for current user.
robertshield 2012/08/05 15:01:12 nit: imo should add a blank line before the commen
gab 2012/08/06 19:39:27 Done.
+ if ((shell_change & ShellUtil::CURRENT_USER) &&
+ !AddRegistryEntries(HKEY_CURRENT_USER, entries)) {
+ ret = false;
+ LOG(ERROR) << "Could not make Chrome default browser (XP/current user).";
+ }
+
+ // Chrome as default browser at system level.
+ if ((shell_change & ShellUtil::SYSTEM_LEVEL) &&
+ !AddRegistryEntries(HKEY_LOCAL_MACHINE, entries)) {
+ ret = false;
+ LOG(ERROR) << "Could not make Chrome default browser (XP/system level).";
+ }
+
+ return ret;
+}
+
} // namespace
const wchar_t* ShellUtil::kRegDefaultIcon = L"\\DefaultIcon";
@@ -914,6 +958,7 @@ const wchar_t* ShellUtil::kRegVerbOpenNewWindow = L"opennewwindow";
const wchar_t* ShellUtil::kRegVerbRun = L"run";
const wchar_t* ShellUtil::kRegCommand = L"command";
const wchar_t* ShellUtil::kRegDelegateExecute = L"DelegateExecute";
+const wchar_t* ShellUtil::kRegOpenWithProgids = L"OpenWithProgids";
bool ShellUtil::QuickIsChromeRegisteredInHKLM(BrowserDistribution* dist,
const string16& chrome_exe,
@@ -1288,29 +1333,8 @@ bool ShellUtil::MakeChromeDefault(BrowserDistribution* dist,
}
}
- // Now use the old way to associate Chrome with supported protocols and file
- // associations. This should not be required on Vista but since some
- // applications still read Software\Classes\http key directly, we have to do
- // this on Vista also.
-
- std::list<RegistryEntry*> entries;
- STLElementDeleter<std::list<RegistryEntry*> > entries_deleter(&entries);
- RegistryEntry::GetUserEntries(
- dist, chrome_exe, GetCurrentInstallationSuffix(dist, chrome_exe),
- &entries);
- // Change the default browser for current user.
- if ((shell_change & ShellUtil::CURRENT_USER) &&
- !AddRegistryEntries(HKEY_CURRENT_USER, entries)) {
- ret = false;
- LOG(ERROR) << "Could not make Chrome default browser (XP/current user).";
- }
-
- // Chrome as default browser at system level.
- if ((shell_change & ShellUtil::SYSTEM_LEVEL) &&
- !AddRegistryEntries(HKEY_LOCAL_MACHINE, entries)) {
+ if (!RegisterChromeAsDefaultForXP(dist, shell_change, chrome_exe))
ret = false;
- LOG(ERROR) << "Could not make Chrome default browser (XP/system level).";
- }
// Send Windows notification event so that it can update icons for
// file associations.
@@ -1334,7 +1358,16 @@ bool ShellUtil::ShowMakeChromeDefaultSystemUI(BrowserDistribution* dist,
// control panel, which is a mess, or pop the concise "How you want to open
// webpages?" dialog. We choose the latter.
// Return true only when the user took an action and there was no error.
- return LaunchSelectDefaultProtocolHandlerDialog(L"http");
+ const bool ret = LaunchSelectDefaultProtocolHandlerDialog(L"http");
+
+ if (ret) {
+ const int shell_change =
+ InstallUtil::IsPerUserInstall(chrome_exe.c_str()) ? CURRENT_USER :
+ SYSTEM_LEVEL;
+ RegisterChromeAsDefaultForXP(dist, shell_change, chrome_exe);
+ }
+
+ return ret;
}
bool ShellUtil::MakeChromeDefaultProtocolClient(BrowserDistribution* dist,
@@ -1413,16 +1446,20 @@ bool ShellUtil::RegisterChromeBrowser(BrowserDistribution* dist,
// Do the full registration if we can do it at user-level or if the user is an
// admin.
if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) {
- std::list<RegistryEntry*> progids;
- STLElementDeleter<std::list<RegistryEntry*> > progids_deleter(&progids);
+ std::list<RegistryEntry*> progid_and_appreg_entries;
+ STLElementDeleter<std::list<RegistryEntry*> > progdid_and_appreg_deleter(
+ &progid_and_appreg_entries);
std::list<RegistryEntry*> shell_entries;
STLElementDeleter<std::list<RegistryEntry*> > shell_deleter(&shell_entries);
- RegistryEntry::GetProgIdEntries(dist, chrome_exe, suffix, &progids);
+ RegistryEntry::GetProgIdEntries(dist, chrome_exe, suffix,
+ &progid_and_appreg_entries);
+ RegistryEntry::GetAppRegistrationEntries(chrome_exe, suffix,
+ &progid_and_appreg_entries);
RegistryEntry::GetShellIntegrationEntries(
dist, chrome_exe, suffix, &shell_entries);
return AddRegistryEntries(user_level ? HKEY_CURRENT_USER :
HKEY_LOCAL_MACHINE,
- progids) &&
+ progid_and_appreg_entries) &&
AddRegistryEntries(root, shell_entries);
}
@@ -1435,10 +1472,11 @@ bool ShellUtil::RegisterChromeBrowser(BrowserDistribution* dist,
ElevateAndRegisterChrome(dist, chrome_exe, suffix, L""))
return true;
- // If we got to this point then all we can do is create ProgIds under HKCU.
+ // If we got to this point then all we can do is create ProgId and basic app
+ // registrations under HKCU.
std::list<RegistryEntry*> entries;
STLElementDeleter<std::list<RegistryEntry*> > entries_deleter(&entries);
- RegistryEntry::GetProgIdEntries(dist, chrome_exe, L"", &entries);
+ RegistryEntry::GetProgIdEntries(dist, chrome_exe, string16(), &entries);
// Prefer to use |suffix|; unless Chrome's ProgIds are already registered with
// no suffix (as per the old registration style): in which case some other
// registry entries could refer to them and since we were not able to set our
@@ -1447,8 +1485,17 @@ bool ShellUtil::RegisterChromeBrowser(BrowserDistribution* dist,
if (!suffix.empty()) {
STLDeleteElements(&entries);
RegistryEntry::GetProgIdEntries(dist, chrome_exe, suffix, &entries);
+ RegistryEntry::GetAppRegistrationEntries(chrome_exe, suffix, &entries);
}
return AddRegistryEntries(HKEY_CURRENT_USER, entries);
+ } else {
+ // The ProgId is registered unsuffixed in HKCU, also register the app with
+ // Windows in HKCU (this was not done in the old registration style and
+ // thus needs to be done after the above check for the unsuffixed
+ // registration).
+ STLDeleteElements(&entries);
+ RegistryEntry::GetAppRegistrationEntries(chrome_exe, string16(), &entries);
+ return AddRegistryEntries(HKEY_CURRENT_USER, entries);
}
return true;
}
« chrome/installer/setup/uninstall.cc ('K') | « chrome/installer/util/shell_util.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698