场景
有时候需要与其他程序进行交互时,自定义协议是一个不错的选择 -- 它能在程序为启动时启动程序然后处理其它程序的动作,而这是其它解决方案,包括 HTTP 请求、共享数据库不能比的。其实日常生活中也有现成的例子,迅雷的自定义协议下载链接、BitTorrent 协议、百度网盘启动本地客户端等等。
使用
- 让程序保持单例启动
- 设置客户端支持的协议(在 Windows 中会写入到注册表)
- 处理命令行参数找到其中需要的
url
信息 - 监听
ready
和second-instance
事件
让程序保持单例启动
参考: app.requestSingleInstanceLock() 注: 仅在单例模式下才能监听
second-instance
事件
// 请求单例锁,避免打开多个 electron 实例
const gotTheLock = app.requestSingleInstanceLock()
if (!gotTheLock) {
app.quit()
return
}
设置客户端支持的协议(在 Windows 中会写入到注册表)
import { app } from 'electron'
import path = require('path')
/**
* 客户端默认支持的协议
*/
export class DefaultProtocolClient {
constructor(public readonly protocol: string) {}
/**
* 注册一个默认支持打开的协议
*/
register() {
// 开发模式下在 window 运行需要做兼容
if (
process.env.NODE_ENV === 'development' &&
process.platform === 'win32'
) {
// 设置 electron.exe 和 app 的路径
app.setAsDefaultProtocolClient(this.protocol, process.execPath, [
path.resolve(process.argv[1]),
])
} else {
app.setAsDefaultProtocolClient(this.protocol)
}
}
/**
* 从命令行参数中找到 url
* @param argv
*/
findUrl(argv: string[]): string | undefined {
const regExp = new RegExp(`^${this.protocol}://`)
return argv.find((str) => regExp.test(str))
}
}
const defaultProtocolClient = new DefaultProtocolClient('custom-protocol')
await defaultProtocolClient.register()
url
信息
处理命令行参数找到其中需要的 添加函数 handleDefaultProtocol
从命令行参数中找到 url 然后处理它。
/**
* 处理客户端支持的默认协议
* @param argv
*/
async function handleDefaultProtocol(argv: string[]) {
const url = defaultProtocolClient.findUrl(argv)
if (!url) {
return
}
await dialog.showMessageBox({
type: 'info',
message: 'window protocol 自定义协议打开',
detail: ` 链接:${url}`,
})
}
ready
和 second-instance
事件
监听 app.addListener('second-instance', async (event, argv) => {
await handleDefaultProtocol(argv)
})
app.addListener('ready', async () => {
await createMainWindow()
await handleDefaultProtocol(process.argv)
})
外部调用
既然我们自定义协议的目的是让外部程序调用,那么如何使用外部调用就很重要了。
首先检查注册表中是否已经包含它了,操作 ctrl+s => 搜索注册表 => 进入注册表 => ctrl+f 查找 custom-protocol
浏览器打开
如上图所示,可以简单在浏览器中输入 custom-protocol://test 来启动程序。
nodejs 示例
在 nodejs 中使用 npm 包 open 可以轻易打开自定义默认链接。
import * as open from 'open'
open('custom-protocol://test')
其实本质上就是拼接命令,然后执行系统命令打开 url,参考它的实现。