引入
很多场景下我们都希望通过url快速唤醒应用,例如百度网盘,在网页中唤醒应用,并传递下载链接,在electron中要实现这样的效果,就需要针对不同的平台做对应的处理。
实现效果
实现步骤
1.主进程中补充调整代码
- windows中需要注册协议,指定被唤醒时如何处理url
- windows当页面被唤醒后,需要监听second-instance 事件,即启动第二个实例的事件,这里我们直接控制应用单实例,当url企图打开第二个实例的时候,我们聚焦第一个实例,并处理url参数
- mac中会监听open-url事件,我们只需在此事件中处理对应的url地址即可
//*************** 应用唤醒相关 ********************/
// 注册协议
const PROTOCOL = "bcxlelectrondemo";
/**添加注册表信息 用于浏览器启动客户端 */
function registerScheme() {
const args = [];
if (!app.isPackaged) {
// 如果是开发阶段,需要把我们的脚本的绝对路径加入参数中
args.push(join(process.argv[1]));
}
// 加一个 `--` 以确保后面的参数不被 Electron 处理
args.push("--");
app.setAsDefaultProtocolClient(PROTOCOL, process.execPath, args);
handleArgv(process.argv);
}
// 处理浏览器打开应用的启动参数信息
function handleArgv(argv: string[]) {
const prefix = `${PROTOCOL}:`;
// 开发阶段,跳过前两个参数(`electron.exe .`)
// 打包后,跳过第一个参数(`myapp.exe`)
const offset = app.isPackaged ? 1 : 2;
const url = argv.find((arg, i) => i >= offset && arg.startsWith(prefix));
if (url) handleUrl(url);
}
// 房间号
let roomCode = "";
// 处理url打开应用的请求
function handleUrl(url: string) {
// bcxlelectrondemo://joinRoom?roomCode=123
const urlObj = new URL(url);
const { searchParams } = urlObj;
roomCode = searchParams.get("roomCode") || "";
if (win && win.webContents) {
win?.webContents.send("launch-app", roomCode);
}
}
// 返回房间号,主要用于mac主动获取,因为mac在执行handleUrl操作时,可能页面窗口还未初始化完成
ipcMain.on("get-roomCode", (e) => {
e.returnValue = roomCode;
});
// 注册协议,用于浏览器打开应用
registerScheme();
// macOS 下通过协议URL启动时,主实例会通过 open-url 事件接收这个 URL
app.on('open-url', (event, urlStr) => {
handleUrl(urlStr);
});
//*************** 应用唤醒相关 ********************/
2.在src目录下创建scripts目录,然后新建一个appInit.ts文件,我们监听来自出主进程的初始化通知
import { ipcRenderer } from "electron";
// 监听初始化
ipcRenderer.on("launch-app", (_, roomCode) => {
console.log("收到来自url的房间号:", roomCode);
});
测试代码
我们在渲染进程中补充代码,主动获取房间号
- 因为应用通过url唤醒时,可能页面窗口还未初始化完成,这时win是null,收不到“launch-app”的监听
- src\components\HelloWorld.vue
<template>
<el-button @click="getRoomCodeByUrl">获取url中传来的房间号</el-button>
</template>
<script>
// 通过浏览器唤醒应用的url获取房间号
function getRoomCodeByUrl() {
const roomCode = ipcRenderer.sendSync("get-roomCode");
myUtils.message(`房间号为:${roomCode}`, "success");
}
</script>
注意:安装后必须打开一次应用【应用会在注册表添加信息】,才能通过url进行唤醒