JavaScript调起本地应用程序
以下内容,自定义部分我也还未经过实际验证,酌情查看。
文章目录
- JavaScript调起本地应用程序
- 确定协议
- 调用协议
- 传参
- 自定义
- 写入协议
- 获取参数
在浏览器中通过
JavaScript
调起本地应用程序的一个可行方法就是
通过协议调起。
具体步骤就两步:
- 确定协议
- 调用协议
确定协议
确定协议的方法要去注册表中看。
window + s
搜索regedit
,打开 注册表编辑器,然后再HKEY_CLASSES_ROOT
下找。
以 微信 为例:可以在HKEY_CLASSES_ROOT
项下找到weixin
项,在weixin
上右键导出注册表,在编辑器(例如:vscdoe
)中打开,可以看到以下内容:
Windows Registry Editor Version 5.00[HKEY_CLASSES_ROOT\weixin]
@="weixinProtocol"
"URL Protocol"="weixinProtocol"[HKEY_CLASSES_ROOT\weixin\DefaultIcon]
@="C:\\Program Files (x86)\\Tencent\\WeChat\\WeChat.exe,1"[HKEY_CLASSES_ROOT\weixin\shell][HKEY_CLASSES_ROOT\weixin\shell\open][HKEY_CLASSES_ROOT\weixin\shell\open\command]
@="\"C:\\Program Files (x86)\\Tencent\\WeChat\\WeChat.exe\" \"%1\""
上面写的你可能一脸懵逼,我给转换下写法:
HKEY_CLASSES_ROOTweixin(Default) "weixinProtocol"URL Protocol "weixinProtocol"DefaultIcon(Default) "C:\Program Files (x86)\Tencent\WeChat\WeChat.exe,1"shellopencommand(Default) "C:\Program Files (x86)\Tencent\WeChat\WeChat.exe" "%1"
这是不是就清楚多了。
除去第一行Windows Registry Editor Version 5.00
,只看下面的转换:
[HKEY_CLASSES_ROOT\weixin]
表示这是HKEY_CLASSES_ROOT
下的weixin
,所以写法是:
HKEY_CLASSES_ROOTweixin
再往下:@
即 (Default)
,其他的就没啥了,自己看下即可。
那么这些里面都是啥意思呢:
weixin
是协议的名称。URL Protocol
表示这是一个URL协议。DefaultIcon
子键指定了协议的图标。shell\open\command
子键指定了打开协议链接时应该运行的命令。
由此确定,微信的协议:weixin
。
调用协议
调用协议就很简单了。一行JavaScript
代码:
window.location.href = 'weixin://';
运行这一行代码,浏览器就会弹出提示框,要我们手动确定是否要打开微信。
或者一行html
代码:
<a href="weixin://">打开微信</a>
传参
具体说明下,调用的应用程序应该怎么传参,要去查看具体的官方文档,这里只是示例,以微信做个示例,不代表微信就这么传。
调起微信时,想给微信传参数,那么只需要在协议后面拼接参数即可,比如:
window.location.href = 'weixin://example?param=value';
那么微信拿到参数的就是'weixin://example?param=value'
。
这点也好解释,前面我粘贴的注册表信息shell/open/command
的协议链接是这样的:
"C:\Program Files (x86)\Tencent\WeChat\WeChat.exe" "%1"
这里的%1
即占位符,我们通过协议打开微信,执行的命令其实是:
"C:\Program Files (x86)\Tencent\WeChat\WeChat.exe" "weixin://example?param=value"
微信可以解析这个参数,然后执行对应的操作。
自定义
自定义不是教怎么去修改别的应用程序的注册表协议,这点我觉得没太大必要。
毕竟你在你的电脑设置了一个特殊的协议,比如把微信的协议weixin://
改成we_weixin://
,但是把调用代码放到别的电脑上还是白搭,别的电脑可不是这样的协议名字。
也不要想着在浏览器上运行JavaScript
时,操纵注册表修改协议,如果JavaScript
运行在浏览器环境里,连操作用户本地文件都不允许,操作注册表,不现实。
自定义 指的是我们自己编写的客户端软件如何被调起。
分为以下几步:
- 编写客户端软件
- 在客户端安装的过程中向用户注册表中注册自定义协议
- 在网页中调用协议
这些专门开发桌面应用程序的开发框架,比如Electron
会给我们提供更多的权限和能力,让我们可以通过执行Javascript
代码来调用本地系统资源。
写入协议
那,如何向注册表写入协议:
可以使用批处理脚本.bat
,也可以通过Node.js
中的child_process
模块执行脚本: (electron
就自带nodejs
环境),也可以使用第三方库,例如regedit
这里先介绍,child_process
如何写入:
const { exec } = require('child_process');const command = 'reg add HKCR\RegistryKey /v YourValueName /t REG_SZ /d "YourValue"';exec(command, (error, stdout, stderr) => {if (error) {console.error(`执行错误: ${error}`);return;}console.log(`stdout: ${stdout}`);console.error(`stderr: ${stderr}`);
});
这里的 reg add
命令用于在注册表中添加一个新的键值对。这需要管理员权限才能执行。
解释下这个command
'reg add HKCU\\Software\\YourRegistryPath /v YourValueName /t REG_SZ /d "YourValue"'
-
reg
: 这是注册表编辑器的命令行工具。 -
add
: 这是 reg 工具的一个子命令,表示要添加一个新的注册表项。 -
HKCR
: 这是注册表的根键之一, 存储了系统中所有已注册的文件类型、协议、COM 对象等信息。 -
RegistryKey
: 这是在HKCU
下的子路径,表示你要添加键值对的具体位置。你可以将RegistryKey
替换为实际的路径。如果路径不存在,reg add 命令会创建它。 -
/v YourValueName
:/v
表示要添加的是一个值(value
),而YourValueName
是这个键值对的名称。你可以将YourValueName
替换为实际的值名称。 -
/t REG_SZ
:/t
表示值的类型(type
),REG_SZ
表示这是一个字符串类型的值。这表示你要添加的值是一个字符串。 -
/d "YourValue"
:/d
表示数据(data
),而"YourValue"
是这个值的具体内容。你可以将YourValue
替换为实际的值。
再说第三方库regedit
如何操作,这就很简单了:
-
下载库
npm i regedit
-
以微信的注册表为例,如何利用
regedit
写入:const regedit = require('regedit');// 协议根路径 const weixinRegistryKey = 'HKCR\\weixin'; const weixinProtocolValue = 'weixinProtocol'; const weixinDefaultIconKey = 'HKCR\\weixin\\DefaultIcon'; const weixinShellOpenCommandKey = 'HKCR\\weixin\\shell\\open\\command'; const weixinExePath = 'C:\\Program Files (x86)\\Tencent\\WeChat\\WeChat.exe';// Write registry values regedit.putValue({[weixinRegistryKey]: {'@': weixinProtocolValue,'URL Protocol': weixinProtocolValue,},[weixinDefaultIconKey]: {'@': `${weixinExePath},1`,},[weixinShellOpenCommandKey]: {'@': `"${weixinExePath}" "%1"`,}, }, (err) => {if (err) {console.error(`Error writing to the registry: ${err.message}`);} else {console.log('Registry updated successfully');} });
协议写好之后,调用协议就不多说了,和上面的一样。
获取参数
自定义了协议,如果用户调用了协议给我们传了参数我们该如何获取呢?
在nodejs
环境下可以使用 process.argv
获取参数。