10

electron 自定义协议 - rxliuli blog

 3 years ago
source link: https://blog.rxliuli.com/p/ff86c5343d38460a8e78a62617f9eace/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

有时候需要与其他程序进行交互时,自定义协议是一个不错的选择 – 它能在程序为启动时启动程序然后处理其它程序的动作,而这是其它解决方案,包括 HTTP 请求、共享数据库不能比的。其实日常生活中也有现成的例子,迅雷的自定义协议下载链接、BitTorrent 协议、百度网盘启动本地客户端等等。

参考: 将当前可执行文件设置为协议的默认处理程序(注册表级别)

  1. 让程序保持单例启动
  2. 设置客户端支持的协议(在 Windows 中会写入到注册表)
  3. 处理命令行参数找到其中需要的 url 信息
  4. 监听 readysecond-instance 事件

让程序保持单例启动

参考: app.requestSingleInstanceLock()
注: 仅在单例模式下才能监听 second-instance 事件

1
2
3
4
5
6
// 请求单例锁,避免打开多个 electron 实例
const gotTheLock = app.requestSingleInstanceLock();
if (!gotTheLock) {
app.quit();
return;
}

设置客户端支持的协议(在 Windows 中会写入到注册表)

参考: app.setAsDefaultProtocolClient(protocol[, path, args])

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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 然后处理它。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* 处理客户端支持的默认协议
* @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}`,
});
}

监听 readysecond-instance 事件

参考: 事件: ‘second-instance’

1
2
3
4
5
6
7
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 可以轻易打开自定义默认链接。

1
2
3
import * as open from "open";

open("custom-protocol://test");

其实本质上就是拼接命令,然后执行系统命令打开 url,参考它的实现


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK