资讯专栏INFORMATION COLUMN

electron程序保护措施(崩溃监控,开机自启,托盘关闭)

2i18ns / 4451人阅读

摘要:当设置了参数时,将作为命令行参数传递。托盘关闭向和微信一样,有的时候我们并不想让用户通过点关闭按钮的时候就关闭程序,而是把程序最小化到托盘,在托盘上做真正的退出操作。首先要监听窗口的关闭事件,阻止用户关闭操作的默认行为。

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

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

1.崩溃监控

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

Event: "crashed"
返回:

event Event
killed Boolean
当渲染进程崩溃或被结束时触发

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

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

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

app.relaunch([options])
options Object (可选)

args String
execPath 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,微信,迅雷等,他们都是通过修改注册表来实现的,我们可以看一下注册表 SoftwareMicrosoftWindowsCurrentVersionRun:

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

发现了一个非常好的写注册表的模块,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 = "SoftwareMicrosoftWindowsCurrentVersionRun";
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("开机自动启设置"); });
    }
  });
}

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

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

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);
      }
    })
  }

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/99066.html

相关文章

  • electron + react + react-router + mobx + webpack 搭

    摘要:调试集成环境选择模块,简单分离开发,测试,线上环境。程序保护开机自启托盘最小化崩溃监控升级一行代码接入升级平台,实现客户端升级功能打包构建一个指令搞定打包项目地址 项目地址 : https://github.com/ConardLi/electron-react electron-react electron + react + react-router + mobx + webpac...

    pingan8787 评论0 收藏0
  • electron实现开机自启+通过链接调起应用

    摘要:实现原理通过修改注册表来实现开机自启和通过链接调起应用类似百度网盘点击连接打开应用程序使用到的插件使用说明将下方例子中的替换为自己的应用别名可以不为名称开机自启开机自启动查看开机自启注册表是否已经注册未注册或注册地址与现地址不一致则进行注 实现原理 通过修改注册表来实现开机自启和通过链接调起应用(类似百度网盘点击连接打开应用程序) 使用到的插件 node-regedit yarn ...

    DevTTL 评论0 收藏0
  • 使用 Electron 将应用程序放入托盘

    摘要:使用将应用程序放入托盘此系列文章的应用示例已发布于可以或下载后运行查看欢迎使用模块允许您在操作系统的通知区域中创建图标此图标还可以附加上下文菜单在浏览器中查看完整文档托盘支持进程示例按钮使用模块向主进程发送消息在主进程中应用程序会被告 使用 Electron 将应用程序放入托盘 此系列文章的应用示例已发布于 GitHub: electron-api-demos-Zh_CN. 可以 Cl...

    XGBCCC 评论0 收藏0
  • 提高云服务器安全等级的七个措施

    摘要:下面就来分享提高云中服务器的安全等级的个措施,让企业有针对性的进行安全防护。对服务器安全而言,安装防火墙非常必要。防火墙对于非法访问具有很好的预防作用,但是安装了防火墙并不等于服务器安全了。 近年以来,云计算已成为信息安全界的宠儿,各家企业前仆后继的跻身于云行列中去。 云技术的出现,确实带给了现代企业非常大的便利,但与好处伴随而来的,也有不能回避的信息安全隐患。 下面就来分享提高云中服...

    cc17 评论0 收藏0

发表评论

0条评论

2i18ns

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<