客户端安装以后,一般来说都有个检查更新的按钮。一点击,就会自动去服务器上拉取最新版本的安装包,然后自动下载安装。本文大概记录一下主要步骤、代码。
1. 创建顶部菜单-检查更新
// 创建electron菜单
const { Menu, dialog, autoUpdater } = require('electron');
// 创建菜单函数
function createTopMenu () {
let topMenu = [{
label: '设置',
submenu: [{
label: '检查更新',
click: () => {
// 点击的时候 给用户一个提示框
dialog.showMessageBox({
type: 'info',
buttons: ['取消', '确认'],
title: '更新提示',
message: '确定更新应用吗?'
}).then(res => {
if (res.response == 1) {
// 如果点击了确认按钮 开始在这里执行远程更新
autoUpdater.checkForUpdates();
}
})
}
}]
}]
}
2. 创建更新程序
const { autoUpdater } = require('electron');
// 更新程序
function setUpdate (url) {
// 设置远程更新地址
// 这个地址就是你服务器存放客户端的地址
// 比如你打包的exe文件和lates.yml文件放在了 http://121.1.1.0:2000/electron/
// 那么 这个url就是 http://121.1.1.0:2000/electron/
try {
autoUpdater.setFeedURL(url);
} catch(err) {
console.err('设置地址出错 --- ', err);
}
// 检查更新事件
autoUpdater.on('check-for-update', () => {
// 将数据发送出去 我这里是前端界面,所以和前端界面通过主进程和渲染进程通信
sendStatusToWindows('正在检查更新...');
})
// 检查可用事件
autoUpdater.on('update-available', () => {
// 将数据发送出去 我这里是前端界面,所以和前端界面通过主进程和渲染进程通信
sendStatusToWindows('正在下载...');
// 下载更新
autoUpdater.downloadUpdate();
})
// 没有可用更新事件
autoUpdater.on('update-not-available', () => {
// 将数据发送出去 我这里是前端界面,所以和前端界面通过主进程和渲染进程通信
sendStatusToWindows('没用可用更新');
})
// 报错事件
autoUpdater.on('error', (err) => {
// 将数据发送出去 我这里是前端界面,所以和前端界面通过主进程和渲染进程通信
sendStatusToWindows(`报错 --- ${err}`);
})
// 下载进度事件
autoUpdater.on('download-progress', (processObj) => {
// 将数据发送出去 我这里是前端界面,所以和前端界面通过主进程和渲染进程通信
sendStatusToWindows(processObj);
})
// 下载完成事件
autoUpdater.on('update-downloaded', () => {
// 将数据发送出去 我这里是前端界面,所以和前端界面通过主进程和渲染进程通信
sendStatusToWindows('下载完成');
// 关闭窗口 启动安装程序
autoUpdater.quitAndInstall();
})
}
// 向前端发消息
function sendStatusToWindows (info) {
const json = JSON.stringfy(info);
// 定义通道名称
const channel = 'app.updater';
// 通过创建的window发送 我这里的变量 win 就是 new BrowserWindow创建的窗口
win.webContents.send(channel, json);
}
3. 注册更新程序
const { app } = require('electron');
// 现在需要在ready生命周期的时候 注册菜单和更新程序
app.whenReady().then(() => {
// 创建浏览器窗口(渲染进程)
let win = new BrowserWindow({
width: 600,
height: 600,
webPreferences: {
contextIsolation: false,
preload,
},
});
// 注册菜单
createTopMenu();
// 注册更新程序
setUpdate('http://127.1.1.1:2000/electron');
......
});
以上步骤基本就构建了完整的通过菜单检查更新。
4. 服务器上传文件
其实,前边已经说了。我们上传服务器的时候,需要上传两个文件。
一个是exe(打包的客户端文件),另一个是lates.yml文件。两者缺一不可。
后者文件内记录你的客户端的发布版本,哈希值,日期等信息。所以,在你进行请求更新的时候,程序会自动对比这些字段,发现有更高版本的程序,会下载更新。
5. 动态配置问题
代码中出现了可能需要动态配置的地方,比如服务器更新地址url。我这里提供两种思路:
第一,客户端安装根路径配置一个config.json,然后通过读取config.json中配置的url字段。
// 使用fs模块读取文件
function loadConfig () {
const configPath = path.join(app.getAppPath(), 'config.json');
if (fs.existsSync(configPath)) {
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
// 获取地址后在给更新程序
setUpdate(config.url);
}
}
// config.json 示例内容如下
{
"url": "http://127.0.0.1:3000/electron/"
}
第二种,是前端界面中直接配置,然后通过electron的主进程和渲染进程通信通道进行交互。
这块代码就不写了,和上边的sendStatusToWindows 思路类似,可以自行编写。