更新应用程序
有几种方法可以为您的 Electron 应用程序提供自动更新。最简单且官方支持的方法是利用内置的 Squirrel 框架和 Electron 的 autoUpdater 模块。
使用云对象存储(无服务器)
对于简单的无服务器更新流程,Electron 的 autoUpdater 模块可以通过指向包含最新版本元数据的静态存储 URL 来检查更新是否可用。
当有新版本可用时,需要将此元数据与版本本身一起发布到云存储。macOS 和 Windows 的元数据格式不同。
发布版本元数据
使用 Electron Forge,您可以通过使用 `macUpdateManifestBaseUrl` 从 ZIP Maker (macOS) 发布元数据 artifact,并使用 `remoteReleases` 从 Squirrel.Windows Maker (Windows) 发布元数据 artifact 来设置静态文件存储更新。
有关端到端示例,请参阅 Forge 的从 S3 自动更新指南。
手动发布
在 macOS 上,Squirrel.Mac 可以通过读取具有以下 JSON 格式的 `releases.json` 文件来接收更新
{
"currentRelease": "1.2.3",
"releases": [
{
"version": "1.2.1",
"updateTo": {
"version": "1.2.1",
"pub_date": "2023-09-18T12:29:53+01:00",
"notes": "Theses are some release notes innit",
"name": "1.2.1",
"url": "https://mycompany.example.com/myapp/releases/myrelease"
}
},
{
"version": "1.2.3",
"updateTo": {
"version": "1.2.3",
"pub_date": "2024-09-18T12:29:53+01:00",
"notes": "Theses are some more release notes innit",
"name": "1.2.3",
"url": "https://mycompany.example.com/myapp/releases/myrelease3"
}
}
]
}
在 Windows 上,Squirrel.Windows 可以通过读取构建过程中生成的 RELEASES 文件来接收更新。此文件详细说明了要更新到的 `.nupkg` 增量包。
B0892F3C7AC91D72A6271FF36905FEF8FE993520 electron-fiddle-0.36.3-full.nupkg 103298365
这些文件应与您的版本位于同一目录中,并位于一个能区分您的应用平台和架构的文件夹结构下。
例如
my-app-updates/
├─ darwin/
│ ├─ x64/
│ │ ├─ my-app-1.0.0-darwin-x64.zip
│ │ ├─ my-app-1.1.0-darwin-x64.zip
│ │ ├─ RELEASES.json
│ ├─ arm64/
│ │ ├─ my-app-1.0.0-darwin-arm64.zip
│ │ ├─ my-app-1.1.0-darwin-arm64.zip
│ │ ├─ RELEASES.json
├─ win32/
│ ├─ x64/
│ │ ├─ my-app-1.0.0-win32-x64.exe
│ │ ├─ my-app-1.0.0-win32-x64.nupkg
│ │ ├─ my-app-1.1.0-win32-x64.exe
│ │ ├─ my-app-1.1.0-win32-x64.nupkg
│ │ ├─ RELEASES
读取版本元数据
使用元数据最简单的方法是安装 update-electron-app,这是一个即用型 Node.js 模块,它设置 autoUpdater 并通过原生对话框提示用户。
对于静态存储更新,将 `updateSource.baseUrl` 参数指向包含您的版本元数据文件的目录。
const { updateElectronApp, UpdateSourceType } = require('update-electron-app')
updateElectronApp({
updateSource: {
type: UpdateSourceType.StaticStorage,
baseUrl: `https://my-bucket.s3.amazonaws.com/my-app-updates/${process.platform}/${process.arch}`
}
})
使用 update.electronjs.org
Electron 团队维护着 update.electronjs.org,这是一个免费的开源 Web 服务,Electron 应用可以使用它进行自我更新。该服务专为满足以下条件的 Electron 应用设计:
- 应用在 macOS 或 Windows 上运行
- 应用有一个公开的 GitHub 仓库
- 构建发布到 GitHub Releases
- 构建是代码签名的 (仅限 macOS)
使用此服务最简单的方法是安装 update-electron-app,这是一个预配置用于 update.electronjs.org 的 Node.js 模块。
使用您选择的 Node.js 包管理器安装该模块
- npm
- Yarn
npm install update-electron-app
yarn add update-electron-app
然后,从您应用的主进程文件中调用更新程序
require('update-electron-app')()
默认情况下,此模块将在应用启动时检查更新,然后每十分钟检查一次。找到更新后,它将在后台自动下载。下载完成后,将显示一个对话框,允许用户重新启动应用。
如果您需要自定义配置,可以将选项传递给 update-electron-app 或直接使用更新服务。
使用其他更新服务
如果您正在开发私有 Electron 应用,或者您没有将版本发布到 GitHub Releases,则可能需要运行自己的更新服务器。
步骤 1:部署更新服务器
根据您的需求,您可以选择其中之一
- Hazel – 适用于私有或开源应用的更新服务器,可免费部署在 Vercel 上。它从 GitHub Releases 中拉取,并利用 GitHub CDN 的强大功能。
- Nuts – 也使用 GitHub Releases,但会在磁盘上缓存应用更新并支持私有仓库。
- electron-release-server – 提供用于处理版本的仪表板,并且不要求版本来源于 GitHub。
- Nucleus – 由 Atlassian 维护的 Electron 应用的完整更新服务器。支持多个应用和通道;使用静态文件存储以最小化服务器成本。
部署更新服务器后,您可以使用 Electron 的 autoUpdater 模块编写应用代码来接收和应用更新。
步骤 2:在应用中接收更新
首先,在您的主进程代码中导入所需的模块。以下代码可能因服务器软件不同而异,但使用 Hazel 时的工作方式与描述相同。
请确保以下代码仅在您的打包应用中执行,而不是在开发环境中执行。您可以使用 app.isPackaged API 来检查环境。
const { app, autoUpdater, dialog } = require('electron')
接下来,构建更新服务器 feed 的 URL,并告知 autoUpdater
const server = 'https://your-deployment-url.com'
const url = `${server}/update/${process.platform}/${app.getVersion()}`
autoUpdater.setFeedURL({ url })
最后一步是检查更新。以下示例将每分钟检查一次
setInterval(() => {
autoUpdater.checkForUpdates()
}, 60000)
一旦您的应用被打包,每发布一个新的 GitHub Release,它都会收到更新。
步骤 3:在更新可用时通知用户
现在您已经为您的应用配置了基本的更新机制,您需要确保在有更新时通知用户。这可以通过使用 autoUpdater API 事件来实现
autoUpdater.on('update-downloaded', (event, releaseNotes, releaseName) => {
const dialogOpts = {
type: 'info',
buttons: ['Restart', 'Later'],
title: 'Application Update',
message: process.platform === 'win32' ? releaseNotes : releaseName,
detail:
'A new version has been downloaded. Restart the application to apply the updates.'
}
dialog.showMessageBox(dialogOpts).then((returnValue) => {
if (returnValue.response === 0) autoUpdater.quitAndInstall()
})
})
还要确保处理错误。以下是将它们记录到 `stderr` 的示例
autoUpdater.on('error', (message) => {
console.error('There was a problem updating the application')
console.error(message)
})
由于 autoUpdate 发出的请求不受您的直接控制,您可能会遇到难以处理的情况(例如更新服务器在身份验证后面)。`url` 字段支持 `file://` 协议,这意味着通过一些努力,您可以绕过过程中的服务器通信方面,从本地目录加载更新。这里有一个示例说明如何实现。
更新服务器规范
对于高级部署需求,您还可以推出自己的与 Squirrel 兼容的更新服务器。例如,您可能希望进行基于百分比的逐步发布,通过独立的发布通道分发您的应用,或将您的更新服务器放在身份验证后面。
Squirrel.Windows 和 Squirrel.Mac 客户端需要不同的响应格式,但您可以通过根据 `process.platform` 的值向不同端点发送请求来为这两个平台使用单个服务器。
const { app, autoUpdater } = require('electron')
const server = 'https://your-deployment-url.com'
// e.g. for Windows and app version 1.2.3
// https://your-deployment-url.com/update/win32/1.2.3
const url = `${server}/update/${process.platform}/${app.getVersion()}`
autoUpdater.setFeedURL({ url })
Windows
Squirrel.Windows 客户端期望更新服务器在您的端点的 `/RELEASES` 子路径返回最新可用构建的 `RELEASES` artifact。
例如,如果您的 feed URL 是 `https://your-deployment-url.com/update/win32/1.2.3`,那么 `https://your-deployment-url.com/update/win32/1.2.3/RELEASES` 端点应返回您希望提供的版本的 `RELEASES` artifact 内容。
B0892F3C7AC91D72A6271FF36905FEF8FE993520 https://your-static.storage/your-app-1.2.3-full.nupkg 103298365
Squirrel.Windows 会进行比较检查以确定当前应用是否应更新到 `RELEASES` 中返回的版本,因此即使没有可用更新,您也应返回响应。
macOS
当有更新可用时,Squirrel.Mac 客户端期望在 feed URL 的端点处获得 JSON 响应。此对象具有一个强制性的 `url` 属性,该属性映射到应用更新的 ZIP 存档。对象中的所有其他属性都是可选的。
{
"url": "https://your-static.storage/your-app-1.2.3-darwin.zip",
"name": "1.2.3",
"notes": "Theses are some release notes innit",
"pub_date": "2024-09-18T12:29:53+01:00"
}
如果没有可用的更新,服务器应返回 204 No Content
HTTP 响应。