博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
electron程序保护措施(崩溃监控,开机自启,托盘关闭)
阅读量:5733 次
发布时间:2019-06-18

本文共 4091 字,大约阅读时间需要 13 分钟。

image

在某种情况下,我们可能希望我们的客户端程序尽可能连续不断的运行在我们的系统中,并保持稳定。

以下几种方式可以帮助我们做到这一点:

1.崩溃监控

electron为我们提供了监听程序崩溃的事件:

Event: 'crashed'返回:event Eventkilled Boolean当渲染进程崩溃或被结束时触发

此事件是用来家庭渲染进程崩溃的,但是当主进程意外崩溃时也会触发该事件。

在监测到程序崩溃后,我们要让程序重新启动,此时我们要首先判断window对象是否被销毁,也就是主进程是否被杀死,还是渲染进程崩溃,同时作出不同的处理。

当mainWin被销毁时我们直接重启整个应用,使用如下api:

app.relaunch([options])options Object (可选)args StringexecPath String (可选)从当前实例退出,重启应用。默认情况下,新的实例会和当前实例使用相同的工作目录以及命令行参数。 当设置了 args 参数时, args 将作为命令行参数传递。 当设置了 execPath ,execPath 将被执行以重新启动,而不是当前的应用程序。请注意, 此方法在执行时不会退出当前的应用程序, 你需要在调用 app.relaunch 方法后再执行 app. quit 或者 app.exit 来让应用重启。

只是渲染进程崩溃,我们只需将其他窗体销毁,然后重新load我们的主窗口。

崩溃重启逻辑:

if (mainWin.isDestroyed()) {    app.relaunch();    app.exit(0);  } else {    BrowserWindow.getAllWindows().forEach((w) => {      if (w.id !== mainWin.id) w.destroy();    });    mainWin.reload();  }

当然,我们还要记录一下程序的崩溃日志,我们要确保日志接口发出成功后再重启我们的程序:

下面是程序崩溃后的完整逻辑:

import { BrowserWindow, app, dialog} from 'electron';  const mainWindow = BrowserWindow.fromId(global.mainId);mainWindow.webContents.on('crashed', () => {   const options = {      type: 'error',      title: '进程崩溃了',      message: '这个进程已经崩溃.',      buttons: ['重载', '退出'],    };       recordCrash().then(() => {      dialog.showMessageBox(options, (index) => {        if (index === 0) reloadWindow(mainWindow);        else app.quit();      });    }).catch((e) => {      console.log('err', e);    });})function recordCrash() {     return new Promise(resolve => {        // 崩溃日志请求成功....       resolve();    })}  function reloadWindow(mainWin) {  if (mainWin.isDestroyed()) {    app.relaunch();    app.exit(0);  } else {    BrowserWindow.getAllWindows().forEach((w) => {      if (w.id !== mainWin.id) w.destroy();    });    mainWin.reload();  }}

写好代码之后,我们可以直接在控制台输入 process.crash()来进行测试,或者直接在任务管理器杀掉我们的进程进行测试。

2.开机自启

开机自启是保证我们的程序能长时间在机器上运行很重要的一点。

电脑上有很多程序都设置了开机自启动,比如qq,微信,迅雷等,他们都是通过修改注册表来实现的,我们可以看一下注册表 \\Software\\Microsoft\\Windows\\CurrentVersion\\Run:

image

所以我们也要将我们程序的路径写到这里。

发现了一个非常好的写注册表的模块,winreg

注意mac不能使用这个模块,所以首先要判断是否为window再引用这个模块。

借助这个模块我们可以非常简单的修改注册表:

const WinReg = require('winreg');const startOnBoot = {  enableAutoStart: function (name, file, callback) {    var key = getKey();    key.set(name, WinReg.REG_SZ, file, callback || noop);  },  disableAutoStart: function (name, callback) {    var key = getKey();    key.remove(name, callback || noop);  },  getAutoStartValue: function (name, callback) {    var key = getKey();    key.get(name, function (error, result) {      if (result) {        callback(result.value);      }      else {        callback(null, error);      }    });  }};function noop() { }const RUN_LOCATION = '\\Software\\Microsoft\\Windows\\CurrentVersion\\Run';function getKey() {  return new WinReg({    hive: WinReg.HKCU, //CurrentUser,    key: RUN_LOCATION  });}export default function autoStart() {  startOnBoot.getAutoStartValue('MY_CLIENT_AUTOSTART', function (value) {    if (!value) {      startOnBoot.enableAutoStart('MY_CLIENT_AUTOSTART', process.execPath, function () { console.log('开机自动启设置'); });    }  });}

执行完程序之后,再看注册表,发现我们程序的路径已经写进去了:

image

然后电脑重启后你的程序就自动启动了。

3.托盘关闭

向qq和微信一样,有的时候我们并不想让用户通过点关闭按钮的时候就关闭程序,而是把程序最小化到托盘,在托盘上做真正的退出操作。

首先要监听窗口的关闭事件,阻止用户关闭操作的默认行为。

mainWindow.on('close', (event) => {    mainWindow.hide();    event.preventDefault();  });

然而这时你发现,这只是最小化了程序,任务栏里程序依然存在,我们需要让程序在任务栏里也消失:

mainWindow.on('close', (event) => {    mainWindow.hide();    mainWindow.setSkipTaskbar(true);    event.preventDefault();  });

这时程序就再也找不到了,任务托盘中也没有我们的程序,所以我们要先创建好任务托盘,并做好事件监听:

function createTray() {    const mainWindow = BrowserWindow.fromId(global.mainId);    tray = new Tray(path.join(global.__dirname, 'icon.ico'));    const contextMenu = Menu.buildFromTemplate([      { label: '退出', click: () => { mainWindow.destroy(); app.quit(); } },    ])    tray.setToolTip('我的客户端')    tray.setContextMenu(contextMenu)    tray.on('click', () => {      if (mainWindow.isVisible()) {        mainWindow.hide();        mainWindow.setSkipTaskbar(false);      } else {        mainWindow.show();        mainWindow.setSkipTaskbar(true);      }    })  }

以上这些操作为我们的程序又增加了好几层的防护措施,我们的程序就不会那么轻而易举的挂掉啦!

转载地址:http://cumwx.baihongyu.com/

你可能感兴趣的文章
更改了mysql的配置文件之后,启动不了mysql服务
查看>>
Activity的启动流程分析
查看>>
河北创新年报统计平台系统整体界面展示,与数据下钻
查看>>
博客园以后不再更新
查看>>
复合数据类型,英文词频统计
查看>>
CentOS 7运维管理笔记(8)----Apache基于域名的虚拟主机配置
查看>>
Codeforces 498A Crazy Town
查看>>
2015 GDUT校赛
查看>>
WCF服务部署到IIS7.5
查看>>
《软件测试自动化之道》读书笔记 之 底层的Web UI 测试
查看>>
mkdocs 生成帮助文档
查看>>
Sencha Touch 载入base64格式的图片数据
查看>>
.NET Core 实践:微服务架构的优点
查看>>
遍历文件夹下所有文件的路径
查看>>
iOS开发-Xcode入门ObjC程序
查看>>
spring多数据源配置
查看>>
struct ip 和struct iphdr && struct icmp 和 struct icmphdr
查看>>
信号量
查看>>
登录时将所有文件(夹)从桌面移除
查看>>
使用Chrome的开发者工具
查看>>