electron自动更新需要用到插件electron-updater,该插件提供了checkForUpdates方法去监听是否需要更新插件,还提供了更新过程的监听函数用于操作应用的更新。
import { autoUpdater } from 'electron-updater';
import { dialog, BrowserWindow ,app } from 'electron';
import path from 'path';
import logger from './util/logger';
import winTool from './WinTools' //窗口工具类函数
// 定义一个标志,如果为 true,表示更新检查正在进行,禁用按钮
let isNext = false;
/**检测更新 */
export const checkUpdate = (currentWin: BrowserWindow) => {
// 更新前,删除本地安装包
let updaterCacheDirName = '应用名-updater'
const updatePendingPath = path.join(autoUpdater?.app?.baseCachePath, updaterCacheDirName, 'pending')
logger.info(`删除本地安装包:${updatePendingPath}`);
//删除本地安装包的文件夹
deleteFolderContents(updatePendingPath)
//默认会自动下载新版本,如果不想自动下载,设置autoUpdater.autoDownload = false
autoUpdater.autoDownload = false;
// 设置更新检测的资源路径,会检测对应路径下的 last.yaml文件中的版本信息 上线后确保该文件能正常访问
if (process.platform == 'darwin') {
autoUpdater.setFeedURL(`${updateUrl}/mac`);
} else if (process.platform == 'linux') {
autoUpdater.setFeedURL(`${updateUrl}/linux`);
} else {
autoUpdater.setFeedURL(`${updateUrl}/package`);
}
//检测更新
autoUpdater.checkForUpdates();
autoUpdater.on('checking-for-update', (res?: any) => {
logger.info('获取版本信息:' + JSON.stringify(res));
});
autoUpdater.on('update-not-available', (res) => {
// currentWin?.webContents.send('message', '没有可更新版本');
logger.info('没有可更新版本');
logger.info('是否显示获取版本信息弹窗:' + isNoUpdate);
dialog.showMessageBox({ message: '没有可更新版本' })
currentWin.webContents.send('afterUpdate');
});
//监听'error'事件
autoUpdater.on('error', (err) => {
dialog.showMessageBox({ title: '更新出错拉!', message: err.message , type:'error'})
currentWin.webContents.send('afterUpdate');
logger.error('更新出错:' + JSON.stringify(err));
});
//监听'update-available'事件,发现有新版本时触发
autoUpdater.on('update-available', (res) => {
logger.info('是否显示更新弹窗' + isUpdate);
logger.info('更新弹窗信息:' + JSON.stringify(res));
dialog
.showMessageBox(currentWin, {
type: 'info',
title: '软件更新',
message: '发现新版本, 确定更新?',
buttons: ['确定', '取消'],
})
.then((resp) => {
if (resp.response === 0) {
autoUpdater.downloadUpdate().then(res=>{
logger.info('下载中:'+JSON.stringify(res))
});
}else{
currentWin.webContents.send('afterUpdate');
}
});
});
// 更新包下载百分比回调
autoUpdater.on('download-progress', function (progressObj) {
logger.info('更新包下载:' + JSON.stringify(progressObj));
currentWin.webContents.send('downloadProgress', progressObj.percent);
});
//监听'update-downloaded'事件,新版本下载完成时触发
autoUpdater.on('update-downloaded', (res:any) => {
logger.info('是否展示安装弹窗:' + isNext);
logger.info('安装:' + JSON.stringify(res));
if (!isNext) {
isNext = true;
dialog
.showMessageBox(currentWin, {
type: 'info',
title: '应用更新',
message:
'需要退出程序和手动关闭设计浏览器才能安装新版本,安装完后需重新安装扩展,是否安装?',
buttons: ['是', '否'],
})
.then((buttonIndex) => {
if (buttonIndex.response === 0) {
//选择是,则退出程序,安装新版本
closeApp()
autoUpdater.quitAndInstall();
}else{
currentWin.webContents.send('afterUpdate');
}
isNext = false;
});
}
});
};
用户通过点击更新按钮去查看版本,当有新版本时,会从package.json中配置的发布地址去下载安装包
"build": {
"publish": [
{
"provider": "generic",
"url": "xxxxx"
}
],
}
主进程接收用户在网页上的操作
//主进程监听版本更新检测
ipcMain.on('check-update', (e: any,id:string) => {
// 获取发送通知的渲染进程窗口
const currentWin = winTool.getWindow(id);
if (currentWin) {
// 升级校验
checkUpdate(currentWin);
}
});
//渲染进程
window.ipcRenderer.send('check-update', 'setting');
渲染进程制作简易的下载进度弹窗
<template>
<el-dialog :title="title" v-model="visible">
<div v-if="process">正在下载安装包:{{ process }} %</div>
</el-dialog>
</template>
<script setup lang="ts">
let process = ref(0);
let visible = ref(false)
ipcRenderer.on('downloadProgress', (_, data: any) => {
console.log('process', data)
process.value = parseInt(data);
});
ipcRenderer.on('beforeUpdate',(_,data:any)=>{
visible.value = true
})
ipcRenderer.on('afterUpdate',(_,data:any)=>{
visible.value = false
})
</script>