1. 安装 electron-updater
在项目中安装 electron-updater 包
npm i electron-updater -S
2. 配置package.json
在构建electron项目的build配置项下增加publish相关配置,provider设定为generic,url为新版本文件存放的地址。这个最终会用来生成latest.yml版本描述文件,auto-update工作时,会查询该文件中的版本信息来判断是否有新版本可供下载。
{
"name": "electron_upgrade_test",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"start": "electron .",
"pack": "electron-builder --dir",
"dist": "electron-builder",
"release": "build"
},
"author": "",
"license": "ISC",
"build": {
"appId": "your.id",
"mac": {
"category": "penghk.app.category.type"
},
"publish": [
{
"provider": "generic",
"url": "http://127.0.0.1:3002/download/"
}
]
},
"devDependencies": {
"electron": "^7.1.7",
"electron-builder": "^21.2.0"
},
"dependencies": {
"electron-log": "^4.0.2",
"electron-updater": "^4.2.0"
}
}
3. 创建 main.js 主进程文件
updateHandle函数用于监听版本更新相关的事件
const { app, BrowserWindow, ipcMain } = require('electron')
const { autoUpdater } = require("electron-updater")
function updateHandle() {
autoUpdater.on('error', function (error) {
sendUpdateMessage('检查更新出错 %s', error)
});
autoUpdater.on('checking-for-update', function () {
sendUpdateMessage('正在检查更新…')
});
autoUpdater.on('update-available', function (info) {
sendUpdateMessage('检测到新版本,正在下载…')
});
autoUpdater.on('update-not-available', function (info) {
sendUpdateMessage('现在使用的已经是最新版本')
});
// 更新下载进度事件
autoUpdater.on('download-progress', function (progressObj) {
win.webContents.send('downloadProgress', progressObj)
});
autoUpdater.on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {
// 渲染层回复立即更新,则自动退出当前程序,然后进行程序更新
ipcMain.on('updateNow', (e, arg) => {
console.log("开始更新");
autoUpdater.quitAndInstall();
});
// 询问渲染层是否立即更新
win.webContents.send('isUpdateNow')
});
ipcMain.on("checkForUpdate",()=> {
// 执行自动更新检查
// 这里有两种"checkForUpdates"和"checkForUpdatesAndNotify"
// 区别在于checkForUpdatesAndNotify检查到新版本时会调用系统的通知组件通知用户有新版本可供下载
// 大家可以根据实际需要自行选择
// autoUpdater.checkForUpdates();
autoUpdater.checkForUpdatesAndNotify();
});
}
// 通过main进程发送事件给renderer进程,提示更新信息
function sendUpdateMessage(text) {
win.webContents.send('message', text)
}
// 保持对window对象的全局引用,如果不这么做的话,当JavaScript对象被
// 垃圾回收的时候,window对象将会自动的关闭
let win
function createWindow () {
// 创建浏览器窗口。
win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
// 加载index.html文件,拼接版本信息到URL的hash中,便于渲染层获取当前版本
win.loadURL(`file://${__dirname}/index.html#v${app.getVersion()}`);
// 打开开发者工具
win.webContents.openDevTools()
// 当 window 被关闭,这个事件会被触发。
win.on('closed', () => {
// 取消引用 window 对象,如果你的应用支持多窗口的话,
// 通常会把多个 window 对象存放在一个数组里面,
// 与此同时,你应该删除相应的元素。
win = null
});
// 监听更新相关事件
updateHandle();
}
// Electron 会在初始化后并准备
// 创建浏览器窗口时,调用这个函数。
// 部分 API 在 ready 事件触发后才能使用。
app.on('ready', createWindow)
// 当全部窗口关闭时退出。
app.on('window-all-closed', () => {
// 在 macOS 上,除非用户用 Cmd + Q 确定地退出,
// 否则绝大部分应用及其菜单栏会保持激活。
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
// 在macOS上,当单击dock图标并且没有其他窗口打开时,
// 通常在应用程序中重新创建一个窗口。
if (win === null) {
createWindow()
}
})
4. 创建 index.html 渲染层视图文件
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>Version Auto Upgrade Demo</title>
</head>
<body>
<h1>Version <span id="version"></span></h1>
<div id="container"></div>
<script>
// 更新版本信息
const version = window.location.hash.substring(1);
document.getElementById('version').innerText = version;
// 消息容器
const container = document.getElementById('container');
const { ipcRenderer } = require('electron');
ipcRenderer.send("checkForUpdate");
ipcRenderer.on("message", (event, text) => {
const message = document.createElement('div');
message.innerText = text;
container.appendChild(message);
});
// 注意:“downloadProgress”事件可能存在无法触发的问题,
// 因为如果安装文件过小的话,很快就下载完成,导致没能达到触发条件。
ipcRenderer.on("downloadProgress", (event, { percent })=> {
console.log(percent);
});
// 接收到主进程有新的版本已经下载完成,询问是否更新。
ipcRenderer.on("isUpdateNow", () => {
if(confirm('确定要现在升级吗?')){
ipcRenderer.send("updateNow");
}
});
</script>
</body>
</html>
附录1:快速搭建本地静态文件服务器
搭建本地静态文件服务器,方便本地调试。
- 在项目目录下创建静态文件存放目录
mkdir -p update_server/download - 全局安装http-server
npm i http-server -g - 启动文件服务器
http-server ./update_server -p 3002 - 将打包好的新版本文件放入
download目录 - 检查是否可以正常访问
http://127.0.0.1:3002/download,如下图
附录2:latest-mac.yml 示例
version为版本字段,来源于打包时项目中的package.json文件的 version字段,如果用户当前程序版本低于该版本,则提示用户进行更新。
sha512字段为对应文件的Hash值,用于校对文件的完整合法性。
version: 1.0.1
files:
- url: electron_upgrade_test-1.0.1-mac.zip
sha512: w5kTV0E2duVr1zw2ZPhJZncWXXwY6Muu6gCGpb3CNQWwqtM/WlCfKMsIIMCZH/FHeoDxF3hJhZR6yUIJSc02fg==
size: 62878761
blockMapSize: 67301
- url: electron_upgrade_test-1.0.1.dmg
sha512: x6ySqvUl8NXZ88rAnn64J36ra9H+Tgecp/QG3MtaNZgFAsp8BEl4UJT8HIXTpFmmMLxpcfVAdhE7Aibe8xQc9Q==
size: 64808426
path: electron_upgrade_test-1.0.1-mac.zip
sha512: w5kTV0E2duVr1zw2ZPhJZncWXXwY6Muu6gCGpb3CNQWwqtM/WlCfKMsIIMCZH/FHeoDxF3hJhZR6yUIJSc02fg==
releaseDate: '2020-01-03T06:36:08.231Z'
最后,文章写得有点仓促,不免会出现不恰当的地方,欢迎大家评论区加以指正,谢谢!