mac系统,如何处理electron的second-instance特例
发布于 作者:苏南大叔 来源:程序如此灵动~
在mac系统下,electron的second-instance事件,是有些特殊的情况的。在本文中,苏南大叔就讲述:在mac系统中的,second-instance事件的特殊情况。主要从两个维度上分析问题,分别是:产品模式(调试还是生产),执行方式(命令行、双击、伪协议)。

本文测试环境:mac/electron@5.0.1。本文所描述的前提,都是mac,不包含win10或者centos等系统。
总前提
mac系统里面的程序,比较特殊。对于具体的程序体来说,即使没有写特殊的单实例代码,正常直接打开程序的时候(比如点击程序图标),也是默认单实例的。第二次点击的时候,是默认激活第一次的实例的。这个就是其特权的情况,根源所在。
对于通过命令行或者伪协议,这种使用了参数进行第二次实例初始化的情况,是有较大概率出现第二个相同的程序窗口的。然而,在实际的应用情景下,这两种情况出现的概率,真的是很少。而且,
- 命令行下(调试模式),触发的是
second-instance事件 - 伪协议下(生产模式),触发的是
open-url事件
相关链接:
基础代码
下述代码都是在主进程中的,分功能模块描述:
基础部分:
const {app, BrowserWindow,dialog} = require('electron')单实例部分(对于生产模式的mac程序没有意义):
const gotTheLock = app.requestSingleInstanceLock();
if (!gotTheLock) {
app.quit();
}注册伪协议部分(对于mac来说,args也是没有任何意义的):
const args = [];
if (!app.isPackaged) {
args.push(path.resolve(process.argv[1]));
}
args.push('--');
const PROTOCOL = 'sunan';
app.setAsDefaultProtocolClient(PROTOCOL, process.execPath, args);处理second-instance事件,(对于mac的生产模式(包括伪协议的情况)无效):
app.on('second-instance', (event, argv) => {
dialog.showMessageBox({
title: "second",
message: "second:" + argv.join(""),
});
});处理open-url事件,(仅针对mac的伪协议和生产模式,有意义。其它操作系统,目前来看,无效):
app.on('open-url', (event, urlStr) => {
dialog.showMessageBox({
title: "open",
message: "open:" + urlStr,
});
});
从最终效果上来说,second-instance中的argv的一部分元素组合到一起,就是open-url中的url。或者说,second-instance需要处理才能获得url,而open-url,不用处理就可以直接获得想要的url信息。
调试模式
- 命令行情况下,会触发
second-instance事件。 - 伪协议情况下,走不通代码,主要是
setAsDefaultProtocolClient的argv这个参数的问题,暂时无处理方案。
生产模式
- 双击程序体,不触发
second-instance事件,这个是mac系统的特殊性决定的。 - 伪协议情况,不触发
second-instance事件,但是会触发open-url事件,第二个参数url就是传递进来的页面链接的字符串。
总结
在mac系统下,对于第二实例的具体处理逻辑,还是有很多特例的。需要大家仔细体会。更多苏南大叔的electron经验文章,请点击: