# 🚀Electron程序的打包与在线升级
📅 2023/4/28
# electron-builder 配置及打包
采用electron-builder 进行打包,该方式可以方便进行在线升级。可以根据需求配置以下的相应字段。下方配置及方法以windows平台作为示例。
{
"build": {
"productName": "应用程序名称",
"appId": "应用程序唯一标识",
"asar": true, //是否采用asar打包
"electronDownload": { //electron镜像地址,由于打包过程中需要下载相应版本及平台的electron包,如果下载失败可以通过此配置设置淘宝镜像下载
"mirror": "https://npm.taobao.org/mirrors/electron/" //设置electron下载镜像
},
"publish": [ //发布信息
{
"provider": "发布平台例如 GitHub等",
"url": "在线更新的地址"
}
],
"files": [ //排除不需要进行打包的文件,通常是一些静态文件,如dll、exe、.node 文件等
"!**/app.asar.unpacked/**"
],
"extraResources": [ //在打包过程中需要移动的文件,上方files字段将静态文件排除后,需要将这些文件放在asar文件之外。
{
"from": "./app.asar.unpacked", //移出路径
"to": "./app.asar.unpacked" //移入路径
}
],
"win": { //windows平台下的打包配置
"target": "nsis", //nsis,支持 x64 和 ia32 架构,dmg,支持 arm64 架构。
"icon": "./XXX.ico" //应用图标
},
"linux": {
"target": [
"AppImage" //Linux平台下构建选项,可以为AppImage、deb、snap等
]
},
"nsis": { //nsis 配置,用于指定在 Windows 平台上使用 NSIS 构建安装程序时的配置选项。
"oneClick": false, //是否默认安装
"allowToChangeInstallationDirectory": true, //是否可以选择安装目录
"allowElevation": true, //是否需要管理员权限
"installerIcon": "./XXX.ico", //安装程序图标
"createDesktopShortcut": true //是否创建快捷方式
}
}
}
如果需要自定义安装程序或界面,可以在nsis字段下使用"include"或"script"字段指定NSIS脚本的路径,用于自定义安装程序。如果提示缺少nsis-resources-xxx等包,可以通过错误信息的下载地址下载,之后手动放到C:/User/用户名/AppData/Local/electron-builder/cache/nsis/目录下。electron-builder 的配置选项很多,上述文件只是配置了一些常用字段,具体可以去electron-builder官网 (opens new window)查看。
electron-builder install-app-deps && electron-builder --win --ia32
通过以上命令可以指定打包windows平台下的32位程序包,在一些老旧的系统上可能会出现打包出来的程序无法运行的情况,可以通过以兼容模式运行尝试解决:右键安装包 --> 属性 --> 兼容性 --> 勾选以兼容模式运行这个程序 --> 选择平台

# Electron 在线升级
# 打包生成文件
通过electron-builder 打包后在 windows 平台下会生成如下文件,其中.exe文件则为windows平台下的安装包,latest.yml为版本信息,用于在线更新。
- builder-debug.yml
- builder-effective-config.yaml
- latest.yml
- .exe 文件
- .exe.blockmap 文件
- 未打包的文件夹,通常以unpacked结尾
# 准备更新服务器
打包完成后需要准备一台可以用于在线更新的服务器。如果没有服务器,暂时可用本地服务模拟,只要可以提供一个在线更新地址即可。
# 程序改造
安装 electron-updater 包进行更新,该包提供了开箱即用的更新功能(windows)
npm i electron-updater
主进程引入 electron-updater 中的 autoUpdater 方法用于自动更新,并监听一系列事件向渲染进程发送消息展示更新进度。
- checking-for-update:当应用程序开始检查是否有可用更新时触发。可以使用此事件显示 "正在检查更新" 的消息或类似的内容。
- update-available:当发现有可用更新时触发。可以使用此事件通知用户有新版本可供下载,并提示他们是否要下载更新。
- update-not-available:当没有可用更新时触发。可以使用此事件通知用户当前已经是最新版本,并提示他们继续使用应用程序。
- download-progress:当更新程序正在下载时触发。可以使用此事件显示下载进度条或百分比,并通知用户下载的速度。
- update-downloaded:当更新程序已经下载完成并准备好安装时触发。可以使用此事件提示用户是否要立即安装更新。
- error:当发生错误时触发。可以使用此事件接受错误信息。
const {app, BrowserWindow} = require('electron')
// 引入自动更新模块
const { autoUpdater } = require('electron-updater')
// 更新地址
const autoUpdaterUrl = '准备好的更新服务器:例如http://localhost:3000/'
//是否自动下载,如果需要强制更新可以设置为true
autoUpdater.autoDownload=false
//设置更新地址
autoUpdater.setFeedURL(autoUpdaterUrl)
const returnData = {
error: { status: -1, msg: "检测更新异常" },
checking: { status: 0, msg: "正在检查应用程序更新" },
updateAva: { status: 1, msg: "检测到新版本,正在下载,请稍后" },
updateNotAva: { status: 2, msg: "您现在使用的版本为最新版本,无需更新!" }
}
/* 检测更新 */
function checkUpdate() {
autoUpdater.checkForUpdates().then(r => console.log('开始更新检测'))
}
/* 开始下载 */
function startDownLoad(){
//当禁用自动下载时需要通过此方法开启下载
autoUpdater.downloadUpdate()
}
/* 安装更新 */
function installNewVersion(){
//下载完成后需要重启APP开启更新,传递的参数分别为是否静默安装、是否立即退出安装
autoUpdater.quitAndInstall(true, true)
}
//更新错误
autoUpdater.on("error", function (error) {
sendUpdateMessage(returnData.error)
})
//检查中
autoUpdater.on("checking-for-update", function () {
sendUpdateMessage(returnData.checking)
})
autoUpdater.on("update-available", function (info) {
sendUpdateMessage(returnData.updateAva)
})
//当前版本为最新版本
autoUpdater.on("update-not-available", function (info) {
setTimeout(function () {
sendUpdateMessage(returnData.updateNotAva)
}, 1000)
})
// 更新下载进度事件
autoUpdater.on("download-progress", function (progressObj) {
sendUpdateProcess(progressObj)
})
autoUpdater.on("update-downloaded", function (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {
sendUpdateMessage("更新完毕")
})
function sendUpdateMessage(text) {
//如果需要,可以创建更新窗口加载更新页面并向渲染进程发送更新监测信息
}
function sendUpdateProcess(text) {
//如果需要,可以创建更新窗口加载更新页面并向渲染进程发送更新进度信息
}
/*自动更新模块结束 */
//此处暴露三个方法:检测更新、开始下载、安装新版本
module.exports = {checkUpdate,startDownLoad,installNewVersion}
上述代码提供了一个自动更新模块,仅需要引入后调用封装好的方法即可实现更新,如果需要显示更新界面,可以创建更新窗口加载更新页面并向渲染进程发送消息实现交互。更新下载的新安装包会在C:/Users/用户名/AppData/Local/xxx-updater 目录下。将打包生成的文件(unpacked结尾文件夹不需要)放到更新目录下,程序则会自动检测到更新的版本。版本号可以在package.json中的version字段指定。