1、注册表里面按照如下格式填写自定义scheme协议导入:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\jdtest]
@="URL:jdtest Protocol"
"URL Protocol"=""
[HKEY_CLASSES_ROOT\jdtest\DefaultIcon]
@="D:\\Program Files (x86)\\Test\\jdtest.exe"
[HKEY_CLASSES_ROOT\Test\shell]
[HKEY_CLASSES_ROOT\Test\shell\open]
[HKEY_CLASSES_ROOT\jdtest\shell\open\command]
@="\"D:\\Program Files (x86)\\Test\\jdtest.exe\" \"%1\""
2、测试html
scheme 协议定义和 http 协议类似,都是标准的 URI 结构。
[scheme:][//host:port][path][?query][#fragment] 不按照此规则也可以
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Scheme</title>
</head>
<body>
<a href="jdtest://jdtest.com:8080/dl/news/open?data=902323¶ms=test
" id="open">打开应用</a>
</body>
</html>
3、写一个简单的jdtest.exe测试用例:
#include <iostream>
int main(int arg, const char *args[])
{
std::cout << "param:" << args[1];
std::cout << "\nHello World!\n";
system("pause");
}
4、浏览器打开测试页面看下效果:
4.1)、浏览器会检查注册表计算机\HKEY_CLASSES_ROOT\jdtest
4.2)、浏览器调用 platform_util::OpenExternal->OpenExternalOnWorkerThread->ShellExecuteA 打开jdtest.exe
【chrome\browser\external_protocol\external_protocol_handler.cc】
OpenExternalOnWorkerThrea定义在[chrome\browser\platform_util_win.cc]
platform_util::OpenExternal(
#if BUILDFLAG(IS_CHROMEOS_ASH)
Profile::FromBrowserContext(web_contents->GetBrowserContext()),
#endif
url);
void OpenExternalOnWorkerThread(const GURL& url) {
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK);
// Quote the input scheme to be sure that the command does not have
// parameters unexpected by the external program. This url should already
// have been escaped.
std::string escaped_url = url.spec();
escaped_url.insert(0, "\"");
escaped_url += "\"";
// According to Mozilla in uriloader/exthandler/win/nsOSHelperAppService.cpp:
// "Some versions of windows (Win2k before SP3, Win XP before SP1) crash in
// ShellExecute on long URLs (bug 161357 on bugzilla.mozilla.org). IE 5 and 6
// support URLS of 2083 chars in length, 2K is safe."
//
// It may be possible to increase this. https://crbug.com/727909
const size_t kMaxUrlLength = 2048;
if (escaped_url.length() > kMaxUrlLength)
return;
// Specify %windir%\system32 as the CWD so that any new proc spawned does not
// inherit this proc's CWD. Without this, uninstalls may be broken by a
// long-lived child proc that holds a handle to the browser's version
// directory (the browser's CWD). A process's CWD is in the standard list of
// directories to search when loading a DLL, and precedes the system directory
// when safe DLL search mode is disabled (not the default). Setting the CWD to
// the system directory is a nice way to mitigate a potential DLL search order
// hijack for processes that don't implement their own mitigation.
base::FilePath system_dir;
base::PathService::Get(base::DIR_SYSTEM, &system_dir);
if (reinterpret_cast<ULONG_PTR>(ShellExecuteA(
NULL, "open", escaped_url.c_str(), NULL,
system_dir.AsUTF8Unsafe().c_str(), SW_SHOWNORMAL)) <= 32) {
// On failure, it may be good to display a message to the user.
// https://crbug.com/727913
return;
}
}
5、jdtest.exe启动接收到请求参数
jdtest://jdtest.com:8080/dl/news/open?data=902323¶ms=test