博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Chrome源码分析----注册默认浏览器
阅读量:4972 次
发布时间:2019-06-12

本文共 14792 字,大约阅读时间需要 49 分钟。

研究了一下Chrome源码中注册默认浏览器的代码,把研究的笔记直接发出来吧.
 
 
 
//-------------------------ShellIntegration::SetAsDefaultBrowser Begin--------------------------- bool ShellIntegration::SetAsDefaultBrowser() {
FilePath chrome_exe; if (!PathService::Get(base::FILE_EXE, &chrome_exe)) {
LOG(ERROR) << "Error getting app exe path"; return false; } // From UI currently we only allow setting default browser for current user. BrowserDistribution* dist = BrowserDistribution::GetDistribution(); if (!ShellUtil::MakeChromeDefault(dist, ShellUtil::CURRENT_USER, chrome_exe.value(), true)) {
LOG(ERROR) << "Chrome could not be set as default browser."; return false; } VLOG(1) << " Chrome registered as default browser."; return true; } //-------------------------ShellIntegration::SetAsDefaultBrowser End--------------------------- //-------------------------ShellUtil::MakeChromeDefault Begin--------------------------- bool ShellUtil::MakeChromeDefault(BrowserDistribution* dist, int shell_change, const std::wstring& chrome_exe, bool elevate_if_not_admin) {
if (!dist->CanSetAsDefault()) return false; //在注册表中写入默认浏览器所需要的项 //这里如果注册不成功也没做任何处理,返回值根本没用. ShellUtil::RegisterChromeBrowser(dist, chrome_exe, L"", elevate_if_not_admin); bool ret = true; // First use the new "recommended" way on Vista to make Chrome default // browser. //vista下注册默认浏览器的方法 //详见http://msdn.microsoft.com/zh-cn/bb776332.aspx if (base::win::GetVersion() >= base::win::VERSION_VISTA) {
VLOG(1) << "Registering Chrome as default browser on Vista."; IApplicationAssociationRegistration* pAAR; HRESULT hr = CoCreateInstance(CLSID_ApplicationAssociationRegistration, NULL, CLSCTX_INPROC, __uuidof(IApplicationAssociationRegistration), (void**)&pAAR); if (SUCCEEDED(hr)) {
std::wstring app_name = dist->GetApplicationName(); std::wstring suffix; if (ShellUtil::GetUserSpecificDefaultBrowserSuffix(dist, &suffix)) app_name += suffix; hr = pAAR->SetAppAsDefaultAll(app_name.c_str()); pAAR->Release(); } if (!SUCCEEDED(hr)) {
ret = false; LOG(ERROR) << "Could not make Chrome default browser."; } } // 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. //在vista之前的系统中注册默认浏览器的方式,由于一些程序依然按照旧的方式读取注册表项来获取默认浏览器 //所以在vista系统中依然会将旧的项写上 std::list
entries; STLElementDeleter
> entries_deleter(&entries); std::wstring suffix; if (!GetUserSpecificDefaultBrowserSuffix(dist, &suffix)) suffix = L""; //获取注册默认浏览器所需的注册表项 RegistryEntry::GetUserEntries(dist, chrome_exe, suffix, &entries); // Change the default browser for current user. //HKEY_CURRENT_USER,在CURRENT_USER用户级上注册 if ((shell_change & ShellUtil::CURRENT_USER) && !AddRegistryEntries(HKEY_CURRENT_USER, entries)) ret = false; // Chrome as default browser at system level. //注册HKEY_LOCAL_MACHINE,如果在chrome中注册默认浏览器仅注册HKEY_CURRENT_USER //在ShellIntegration::SetAsDefaultBrowser代码中写死 if ((shell_change & ShellUtil::SYSTEM_LEVEL) && !AddRegistryEntries(HKEY_LOCAL_MACHINE, entries)) ret = false; // Send Windows notification event so that it can update icons for // file associations. //通知windows为修改的文件关联刷新图标 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); return ret; } //-------------------------ShellUtil::MakeChromeDefault End--------------------------- //-------------------------ShellUtil::RegisterChromeBrowser Begin--------------------------- bool ShellUtil::RegisterChromeBrowser(BrowserDistribution* dist, const std::wstring& chrome_exe, const std::wstring& unique_suffix, bool elevate_if_not_admin) {
if (!dist->CanSetAsDefault()) return false; // First figure out we need to append a suffix to the registry entries to // make them unique. //是否在注册的名字后加上当前用户名以保证其唯一 std::wstring suffix; if (!unique_suffix.empty()) {
suffix = unique_suffix; } else if (InstallUtil::IsPerUserInstall(chrome_exe.c_str()) && !GetUserSpecificDefaultBrowserSuffix(dist, &suffix) && !AnotherUserHasDefaultBrowser(dist, chrome_exe)) {
suffix = L""; } // Check if Chrome is already registered with this suffix. //判断当前浏览器是否已经注册,如果已经注册则不再重复注册 //这里只判断键值是否存在,没有比对值是否和当前要注册的相同,所以可能会有问题 if (IsChromeRegistered(dist, chrome_exe, suffix)) return true; // If user is an admin try to register and return the status. // 如果当前是管理员权限运行,在HKEY_LOCAL_MACHINE中直接注册数据 if (IsUserAnAdmin()) {
std::list
entries; STLElementDeleter
> entries_deleter(&entries); RegistryEntry::GetProgIdEntries(dist, chrome_exe, suffix, &entries); RegistryEntry::GetSystemEntries(dist, chrome_exe, suffix, &entries); return AddRegistryEntries(HKEY_LOCAL_MACHINE, entries); } // If user is not an admin and OS is Vista, try to elevate and register. //如果是windows vista又没有管理员权限,是没有权限写入HKEY_LOCAL_MACHINE的 //windows的提升权限只能在进程边界上进行,所以打开另一个程序弹出UAC注册数据 if (elevate_if_not_admin && base::win::GetVersion() >= base::win::VERSION_VISTA && ElevateAndRegisterChrome(dist, chrome_exe, suffix)) return true; // If we got to this point then all we can do is create ProgIds under HKCU // on XP as well as Vista. //如果执行到这里,说明确实得不到权限写入HKEY_LOCAL_MACHINE了,只能把数据注册在HKEY_CURRENT_USER下了 std::list
entries; STLElementDeleter
> entries_deleter(&entries); RegistryEntry::GetProgIdEntries(dist, chrome_exe, L"", &entries); return AddRegistryEntries(HKEY_CURRENT_USER, entries); } //-------------------------ShellUtil::RegisterChromeBrowser End--------------------------- //-------------------------IsChromeRegistered Begin--------------------------- // This method checks if Chrome is already registered on the local machine. // It gets all the required registry entries for Chrome and then checks if // they exist in HKLM. Returns true if all the entries exist, otherwise false. bool IsChromeRegistered(BrowserDistribution* dist, const std::wstring& chrome_exe, const std::wstring& suffix) { bool registered = true; std::list
entries; STLElementDeleter
> entries_deleter(&entries); RegistryEntry::GetProgIdEntries(dist, chrome_exe, suffix, &entries); RegistryEntry::GetSystemEntries(dist, chrome_exe, suffix, &entries); //仅仅判断是否存在,有一项不存在就跳出循环 for (std::list
::const_iterator itr = entries.begin(); itr != entries.end() && registered; ++itr) { // We do not need registered = registered && ... since the loop condition // is set to exit early. registered = (*itr)->ExistsInHKLM(); } return registered; } //-------------------------IsChromeRegistered End--------------------------- //-------------------------GetProgIdEntries Begin--------------------------- // This method returns a list of all the registry entries that // are needed to register Chrome ProgIds. static bool GetProgIdEntries(BrowserDistribution* dist, const std::wstring& chrome_exe, const std::wstring& suffix, std::list
* entries) { std::wstring icon_path = ShellUtil::GetChromeIcon(dist, chrome_exe); std::wstring open_cmd = ShellUtil::GetChromeShellOpenCmd(chrome_exe); // File association ProgId // Software\Classes\ChromeHTML\ std::wstring chrome_html_prog_id(ShellUtil::kRegClasses); file_util::AppendToPath(&chrome_html_prog_id, ShellUtil::kChromeHTMLProgId); chrome_html_prog_id.append(suffix); //写在Software\Classes\ChromeHTML\下 ProgId的类型描述 //const wchar_t* ShellUtil::kChromeHTMLProgIdDesc = L"Chrome HTML Document" entries->push_front(new RegistryEntry( chrome_html_prog_id, ShellUtil::kChromeHTMLProgIdDesc)); //写在Software\Classes\ChromeHTML\下 declares a custom protocol handler //Under this new key, the URL Protocol string value indicates that this key declares a custom protocol handler. // Without this key, the handler application will not launch. The value should be an empty string. //见http://msdn.microsoft.com/en-us/library/ie/aa767914(v=vs.85).aspx //Registry value name that is needed for ChromeHTML ProgId //static const wchar_t* kRegUrlProtocol = "URL Protocol"; entries->push_front(new RegistryEntry( chrome_html_prog_id, ShellUtil::kRegUrlProtocol, L"")); //写Software\Classes\ChromeHTML\DefaultIcon value:chrome.exe所在路径 //关联文件的默认图标路径,chrome直接使用程序图标,所以value是chrome.exe所在路径 entries->push_front(new RegistryEntry( chrome_html_prog_id + ShellUtil::kRegDefaultIcon, icon_path)); //写Software\Classes\ChromeHTML\shell\open\command value:chrome.exe所在路径 //打开ChromeHTML时使用的程序所在位置 entries->push_front(new RegistryEntry( chrome_html_prog_id + ShellUtil::kRegShellOpen, open_cmd)); return true; } //-------------------------GetProgIdEntries End--------------------------- //-------------------------GetSystemEntries Begin--------------------------- // This method returns a list of all the system level registry entries that // are needed to register Chrome on the machine. static bool GetSystemEntries(BrowserDistribution* dist, const std::wstring& chrome_exe, const std::wstring& suffix, std::list
* entries) { std::wstring icon_path = ShellUtil::GetChromeIcon(dist, chrome_exe); std::wstring quoted_exe_path = L"\"" + chrome_exe + L"\""; std::wstring app_name = dist->GetApplicationName() + suffix; std::wstring start_menu_entry(ShellUtil::kRegStartMenuInternet); start_menu_entry.append(L"\\" + app_name); //开始菜单处的浏览器显示 //Software\Clients\StartMenuInternet\Chrome value是Chrome entries->push_front(new RegistryEntry(start_menu_entry, app_name)); //开始菜单浏览器的打开命令 //Software\Clients\StartMenuInternet\Chrome\shell\open\command value是exe所在路径,这里还加了一个引号 entries->push_front(new RegistryEntry( start_menu_entry + ShellUtil::kRegShellOpen, quoted_exe_path)); //开始菜单显示的浏览器图标 //Software\Clients\StartMenuInternet\Chrome\DefaultIcon value是exe所在路径 entries->push_front(new RegistryEntry( start_menu_entry + ShellUtil::kRegDefaultIcon, icon_path)); //Software\Clients\StartMenuInternet\Chrome\InstallInfo //详见http://msdn.microsoft.com/en-us/library/cc144109(VS.85).aspx std::wstring install_info(start_menu_entry + L"\\InstallInfo"); // TODO: use CommandLine API instead of constructing command lines. entries->push_front(new RegistryEntry(install_info, L"ReinstallCommand", quoted_exe_path + L" --" + ASCIIToWide(switches::kMakeDefaultBrowser))); entries->push_front(new RegistryEntry(install_info, L"HideIconsCommand", quoted_exe_path + L" --" + ASCIIToWide(switches::kHideIcons))); entries->push_front(new RegistryEntry(install_info, L"ShowIconsCommand", quoted_exe_path + L" --" + ASCIIToWide(switches::kShowIcons))); entries->push_front(new RegistryEntry(install_info, L"IconsVisible", 1)); //Software\Clients\StartMenuInternet\Chrome\Capabilities //http://msdn.microsoft.com/en-us/library/cc144154(VS.85).aspx std::wstring capabilities(start_menu_entry + L"\\Capabilities"); entries->push_front(new RegistryEntry(ShellUtil::kRegRegisteredApplications, app_name, capabilities)); entries->push_front(new RegistryEntry( capabilities, L"ApplicationDescription", dist->GetLongAppDescription())); entries->push_front(new RegistryEntry( capabilities, L"ApplicationIcon", icon_path)); entries->push_front(new RegistryEntry( capabilities, L"ApplicationName", app_name)); entries->push_front(new RegistryEntry(capabilities + L"\\StartMenu", L"StartMenuInternet", app_name)); //接下来是把文件扩展名和协议与html_prog_id关联上,就是在GetProgIdEntries写入的那个 //比如Software\Clients\StartMenuInternet\Chrome\Capabilities\FileAssociations //name 是.htm value是ChromeHTMl std::wstring html_prog_id(ShellUtil::kChromeHTMLProgId); html_prog_id.append(suffix); for (int i = 0; ShellUtil::kFileAssociations[i] != NULL; i++) { entries->push_front(new RegistryEntry( capabilities + L"\\FileAssociations", ShellUtil::kFileAssociations[i], html_prog_id)); } //Software\Clients\StartMenuInternet\Chrome\Capabilities\URLAssociations //其它是一样的 for (int i = 0; ShellUtil::kProtocolAssociations[i] != NULL; i++) { entries->push_front(new RegistryEntry( capabilities + L"\\URLAssociations", ShellUtil::kProtocolAssociations[i], html_prog_id)); } //Software\Microsoft\Windows\CurrentVersion\App Paths\Chrome.exe //注册exe所在目录和路径 FilePath chrome_path(chrome_exe); std::wstring app_path_key(ShellUtil::kAppPathsRegistryKey); file_util::AppendToPath(&app_path_key, chrome_path.BaseName().value()); entries->push_front(new RegistryEntry(app_path_key, chrome_exe)); 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; } //-------------------------GetSystemEntries End--------------------------- //-------------------------GetUserEntries Begin--------------------------- //XP下使用的项 //这个博文写的很清楚了 //http://www.cnblogs.com/greenerycn/archive/2010/08/13/how_to_set_default_browser.html // This method returns a list of all the user level registry entries that // are needed to make Chrome default browser. static bool GetUserEntries(BrowserDistribution* dist, const std::wstring& chrome_exe, const std::wstring& suffix, std::list
* entries) { // File extension associations. std::wstring html_prog_id(ShellUtil::kChromeHTMLProgId); html_prog_id.append(suffix); for (int i = 0; ShellUtil::kFileAssociations[i] != NULL; i++) { std::wstring ext_key(ShellUtil::kRegClasses); file_util::AppendToPath(&ext_key, ShellUtil::kFileAssociations[i]); entries->push_front(new RegistryEntry(ext_key, html_prog_id)); } // Protocols associations. std::wstring chrome_open = ShellUtil::GetChromeShellOpenCmd(chrome_exe); std::wstring chrome_icon = ShellUtil::GetChromeIcon(dist, chrome_exe); for (int i = 0; ShellUtil::kProtocolAssociations[i] != NULL; i++) { std::wstring url_key(ShellUtil::kRegClasses); file_util::AppendToPath(&url_key, ShellUtil::kProtocolAssociations[i]); //
\Software\Classes\
\DefaultIcon std::wstring icon_key = url_key + ShellUtil::kRegDefaultIcon; entries->push_front(new RegistryEntry(icon_key, chrome_icon)); //
\Software\Classes\
\shell\open\command std::wstring shell_key = url_key + ShellUtil::kRegShellOpen; entries->push_front(new RegistryEntry(shell_key, chrome_open)); //
\Software\Classes\
\shell\open\ddeexec std::wstring dde_key = url_key + L"\\shell\\open\\ddeexec"; entries->push_front(new RegistryEntry(dde_key, L"")); //
\Software\Classes\
\shell\@ std::wstring protocol_shell_key = url_key + ShellUtil::kRegShellPath; entries->push_front(new RegistryEntry(protocol_shell_key, L"open")); } // start->Internet shortcut. std::wstring start_menu(ShellUtil::kRegStartMenuInternet); std::wstring app_name = dist->GetApplicationName() + suffix; entries->push_front(new RegistryEntry(start_menu, app_name)); return true; } //-------------------------GetUserEntries End---------------------------

转载于:https://www.cnblogs.com/Entreri/archive/2012/02/05/2339145.html

你可能感兴趣的文章
combobox和textbox中输入数据为非数字leave时的公用事件,只需要在控件的leave事件中选择本事件即可...
查看>>
纵越6省1市-重新启动
查看>>
hive安装以及hive on spark
查看>>
勇者无畏
查看>>
12864点阵液晶显示模块的原理和实例程序(HJ12864M-1)
查看>>
jz1074 【基础】寻找2的幂
查看>>
Wannafly模拟赛5 A 思维 D 暴力
查看>>
C#控制台程序实现鼠标左右手习惯切换
查看>>
C++ 继承、函数重载
查看>>
Javascript获取select下拉框选中的的值
查看>>
并发编程注意的问题
查看>>
angular--ngResource的简单使用
查看>>
android本地数据库,微信数据库WCDB for Android 使用实例
查看>>
如何快速三个月成为一个领域的高手的四个方法
查看>>
[51nod]1347 旋转字符串
查看>>
【Linux开发】CCS远程调试ARM,AM4378
查看>>
springmvc常用注解标签详解
查看>>
Linux之ssh服务介绍
查看>>
Sql语句里的递归查询(转)
查看>>
[JAVA]《Java 核心技术》(一)
查看>>