通过electron-updater方案进行 全量 自升级方案图如下:
一、配置
在package.json文件中配置publish字段,用来生成latest.yml文件,该文件是用来判断版本升级的,在打包过程中生成。
一旦修改了latest.yml文件,则需要重新打包生成,否则更新失败。
这里也可以不配置url字段,在main.js中手动配置,使用autoUpdater.setFeedURL
方法配置即可
"build": {
"productName": "软件名称",
"copyright": "copyright© xxx.,Ltd",
"appId": "xxx",
"asar": true,
"directories": {
"output": "build"
},
"publish": {
"provider": "generic",
"url": "服务端更新接口地址",
"channel": "latest"
}
二、方法
- 监听autoUpdater的事件,一有更新状态变化就会发事件
- error 检查更新错误
- checking-for-update 正在检查更新
- update-available 有新的可用更新
- update-not-available 没有可用的更新,也就是当前是最新版本
- download-progress 正在下载更新版,会有更新进度对象
- update-downloaded 新安装包下载完成
- 还有一些 api 可以控制流程
- .checkForUpdates() 执行一次检查更新
- .checkForUpdatesAndNotify() 执行一次检查更新,如果有新的可用更新,还会自定弹出一个自带的通知提示告诉用户有新的更新
- .downloadUpdate(cancellationToken) 执行下载安装包
- .quitAndInstall(isSilent, isForceRunAfter) 退出应用并安装更新, isSilent 是否静默更新,isForceRunAfter更新完后是否立即运行
- 还有一些配置项
- autoDownload = true 有可用更新时是否自动下载
- autoInstallOnAppQuit = true 如果安装包下载好了,那么当应用退出后是否自动安装更新
- allowPrerelease = false 是否接受开发版,测试版之类的版本号
- allowDowngrade = false 是否可以回退版本,比如从开发版降到旧的稳定版
/**
* Auto Updater
*
* Uncomment the following code below and install `electron-updater` to
* support auto updating. Code Signing with a valid certificate is required.
* https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-electron-builder.html#auto-updating
*/
// 更新地址
const updateURL = "服务端更新接口地址"
// 检测更新
export function handleUpdate() {
const message = {
error: '检查更新出错',
checking: '正在检查更新…',
updateAva: '正在更新',
updateNotAva: '已经是最新版本',
downloadProgress: '正在下载...'
}
// 设置是否自动下载,默认是true,当点击检测到新版本时,会自动下载安装包,所以设置为false
autoUpdater.autoDownload = false
autoUpdater.setFeedURL(updateURL)
autoUpdater.on('error', function (e) {
log.warn('error', e);
sendUpdateMessage({ cmd: 'error', message: message.error })
})
autoUpdater.on('checking-for-update', function () {
log.warn(message.checking)
sendUpdateMessage({ cmd: 'checking-for-update', message: message.checking })
})
autoUpdater.on('update-available', function (info) {
log.warn(message.updateAva)
sendUpdateMessage({ cmd: 'update-available', message: message.updateAva, info })
})
autoUpdater.on('update-not-available', function (info) {
log.warn(message.updateNotAva)
sendUpdateMessage({ cmd: 'update-not-available', message: message.updateNotAva, info: info })
})
// 更新下载进度事件
autoUpdater.on('download-progress', function (progressObj) {
log.warn('触发下载。。。')
log.warn(progressObj)
sendUpdateMessage({ cmd: 'downloadProgress', message: message.downloadProgress, progressObj })
})
autoUpdater.on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {
// ipcMain.on('isUpdateNow', (e, arg) => {
log.warn('开始更新')
autoUpdater.quitAndInstall()
mainWindow.destroy()
// callback()
// })
// sendUpdateMessage({ cmd: 'isUpdateNow', message: null })
})
ipcMain.on('checkForUpdate', () => {
log.warn('执行自动更新检查')
autoUpdater.checkForUpdates()
})
ipcMain.on('downloadUpdate', () => {
log.warn('执行下载')
autoUpdater.downloadUpdate()
})
}
// 通过main进程发送事件给renderer进程,提示更新信息
function sendUpdateMessage(data) {
mainWindow.webContents.send('message', data)
}
三、update页面
- 发送请求检测消息,checkForUpdate
- 检测出错或没有新版本,进入主界面
- 如果有新版本,发送下载新版本请求:downloadUpdate
其中,在主进程download-progress事件的监测中返回的消息中可以取到如下信息
/**
* progressObj
* {
* bytesPerSecond // 网速
* delta
* percent // 已下载百分比
* total // 包大小
* transferred // 已下载大小
* }
*/
this.hasUpdate = true;
this.progress = Math.trunc(progressObj.percent) || 0;
this.total = fomatFloat(progressObj.total / 1000000, 1);
this.transferred = fomatFloat(progressObj.transferred / 1000000, 1);
四、首页轮询检测更新
- 监测主进程中updater返回的消息
- 如果有新的版本,对比当前已跳过版本skipVersion(ex: 1.0.0===1.0.0),如果一致则不提示,否则弹出提示更新窗口
- 在更新弹出中,点击确定,则将路由跳转至update页面;点击取消,则记录当前版本,下次监测更新时,走第2步
优点:
- 配置简单,只需添加publish;
- 代码逻辑简单,只需添加autoUpdater逻辑
缺点:
- 安装包体积过大时,浪费带宽,增加用户升级时间,
而且目前观察,升级过程网速很慢,基本2kb/s,网速慢的原因是我的服务器带宽(1Mb)很慢导致的~~ - 小功能没有必要进行全量升级