当前位置: 首页 > 后端技术 > Node.js

Electron程序保护措施(崩溃监控、自启动、托盘关闭)

时间:2023-04-03 12:50:49 Node.js

在某些情况下,我们可能希望我们的客户端程序在我们的系统中尽可能持续运行并保持稳定。以下几种方式可以帮助我们做到这一点:1.崩溃监听Electron为我们提供了监听器崩溃的事件:Event:'crashed'returns:eventEventkilledBoolean当渲染进程崩溃或者结束时触发该事件home渲染进程崩溃,但当主进程意外崩溃时也会触发此事件。检测到程序崩溃后,我们需要重启程序。这时候首先要判断window对象是否被销毁,即主进程是否被杀死,或者渲染进程是否崩溃,同时进行不同的处理。当mainWin被销毁后,我们直接重启整个应用,使用如下api:app.relaunch([options])optionsObject(optional)argsStringexecPathString(optional)退出当前实例并重启应用。默认情况下,新实例将使用与当前实例相同的工作目录和命令行参数。设置args参数后,args将作为命令行参数传递。当设置了execPath时,会执行execPath来重启,而不是当前应用程序。请注意,该方法执行时不会退出当前应用,需要在调用app.relaunch方法后执行app.quit或app.exit才能重启应用。只是渲染进程崩溃了,我们只是销毁其他窗口并重新加载我们的主窗口。崩溃重启逻辑:if(mainWin.isDestroyed()){app.relaunch();应用程序退出(0);}else{BrowserWindow.getAllWindows().forEach((w)=>{if(w.id!==mainWin.id)w.destroy();});mainWin.reload();}当然,我们还需要记录程序的崩溃日志。在重启我们的程序之前,我们需要确保日志接口发送成功:下面是程序崩溃后的完整逻辑:import{BrowserWindow,app,dialog}from'electron';constmainWindow=BrowserWindow.fromId(global.mainId);mainWindow.webContents.on('crashed',()=>{constoptions={type:'error',title:'Theprocesshascrashed',message:'Thisprocesshascrashed.',buttons:['重新加载','退出'],};recordCrash().then(()=>{dialog.showMessageBox(options,(index)=>{if(index===0)reloadWindow(mainWindow);elseapp.quit();});}).catch((e)=>{console.log('err',e);});})functionrecordCrash(){returnnewPromise(resolve=>{//崩溃日志请求成功....resolve();})}functionreloadWindow(mainWin){if(mainWin.isDestroyed()){app.re发射();应用程序退出(0);}else{BrowserWindow.getAllWindows().forEach((w)=>{if(w.id!==mainWin.id)w.destroy();});主温.reload();}}写好代码后,我们可以直接在控制台输入process.crash()进行测试,或者直接在任务管理器中kill我们的进程进行测试,这对于保证我们的程序能够长时间在机器上运行是非常重要的时间。电脑上有很多程序是设置自动启动的,比如qq、微信、迅雷等,都是通过修改注册表来实现的,我们可以看看注册表\\Software\\Microsoft\\Windows\\CurrentVersion\\Run:所以我们也要把我们程序的路径写在这里。我找到了一个非常好的用于编写注册表的模块。winreg注意到这个模块不能被mac使用,所以首先要判断是不是window,然后引用这个模块。借用这个模块我们可以非常简单的修改注册表:constWinReg=require('winreg');conststartOnBoot={enableAutoStart:function(name,file,callback){varkey=getKey();key.set(name,WinReg.REG_SZ,file,callback||noop);},disableAutoStart:function(name,callback){varkey=getKey();key.remove(名称,回调||noop);},getAutoStartValue:function(name,callback){varkey=getKey();key.get(name,function(error,result){if(result){callback(result.value);}else{callback(null,error);}});}};functionnoop(){}constRUN_LOCATION='\\Software\\Microsoft\\Windows\\CurrentVersion\\Run';functiongetKey(){returnnewWinReg({hive:WinReg.HKCU,//CurrentUser,key:RUN_LOCATION});}exportdefaultfunctionautoStart(){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();});那么程序就会找不到了,任务托盘里也没有程序了,所以我们需要先创建任务托盘,做好事件监听:fromId(global.mainId);tray=newTray(path.join(global.__dirname,'icon.ico'));constcontextMenu=Menu.buildFromTemplate([{label:'Exit',click:()=>{mainWindow.destroy();app.quit();}},])tray.setToolTip('Myclient')托盘。setContextMenu(contextMenu)tray.on('click',()=>{if(mainWindow.isVisible()){mainWindow.hide();mainWindow.setSkipTaskbar(false);}else{mainWindow.show();mainWindow.setSkipTaskbar(true);}})}上面的操作给我们的程序加了几层保护措施,我们的程序就不会那么容易挂掉了!