跳至主要内容

更新应用程序

有几种方法可以为您的 Electron 应用程序提供自动更新。最简单且官方支持的方法是利用内置的 Squirrel 框架和 Electron 的 autoUpdater 模块。

使用云对象存储(无服务器)

对于简单的无服务器更新流程,Electron 的 autoUpdater 模块可以通过指向包含最新发布元数据的静态存储 URL 来检查是否有更新可用。

当有新版本可用时,此元数据需要与版本本身一起发布到云存储。元数据格式对于 macOS 和 Windows 不同。

发布发布元数据

使用 Electron Forge,您可以通过从 ZIP Maker(macOS)使用 macUpdateManifestBaseUrl 和 Squirrel.Windows Maker(Windows)使用 remoteReleases 发布元数据工件来设置静态文件存储更新。

有关端到端示例,请参阅 Forge 的 从 S3 自动更新 指南。

手动发布

在 macOS 上,Squirrel.Mac 可以通过读取具有以下 JSON 格式的 releases.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 增量包。

RELEASES
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 参数指向包含您的发布元数据文件的目录。

main.js
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,这是一个免费的开源网络服务,Electron 应用程序可以使用它来进行自我更新。该服务专为满足以下条件的 Electron 应用程序而设计

  • 应用程序在 macOS 或 Windows 上运行
  • 应用程序有一个公共 GitHub 存储库
  • 构建发布到 GitHub Releases
  • 构建已 代码签名 **(仅限 macOS)**

使用此服务的最佳方法是安装 update-electron-app,这是一个为与 update.electronjs.org 一起使用而预先配置的 Node.js 模块。

使用您选择的 Node.js 包管理器安装该模块

npm install update-electron-app

然后,从应用程序的主进程文件调用更新程序

main.js
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 来检查环境。

main.js
const { app, autoUpdater, dialog } = require('electron')

接下来,构造更新服务器提要的 URL,并告诉 autoUpdater 有关它。

main.js
const server = 'https://your-deployment-url.com'
const url = `${server}/update/${process.platform}/${app.getVersion()}`

autoUpdater.setFeedURL({ url })

作为最后一步,检查更新。以下示例将每分钟检查一次

main.js
setInterval(() => {
autoUpdater.checkForUpdates()
}, 60000)

打包您的应用程序后,它将为您发布的每个新的 GitHub Release 接收更新。

步骤 3:在更新可用时通知用户

现在,您已经为您的应用程序配置了基本的更新机制,您需要确保在有更新时会通知用户。这可以通过使用 autoUpdater API 事件 来实现

main.js
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 的示例

main.js
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 的值将请求发送到不同的端点来使用单个服务器为两个平台提供服务。

main.js
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 工件。

例如,如果您的提要 URL 是 https://your-deployment-url.com/update/win32/1.2.3,那么 https://your-deployment-url.com/update/win32/1.2.3/RELEASES 端点应返回您要提供版本的 RELEASES 工件的内容。

https://your-deployment-url.com/update/win32/1.2.3/RELEASES
B0892F3C7AC91D72A6271FF36905FEF8FE993520 https://your-static.storage/your-app-1.2.3-full.nupkg 103298365

Squirrel.Windows 会执行比较检查,以查看当前应用程序是否应该更新到 RELEASES 中返回的版本,因此即使没有可用的更新,您也应返回响应。

macOS

当有更新可用时,Squirrel.Mac 客户端希望在提要 URL 的端点处获得 JSON 响应。此对象具有一个强制性的 url 属性,该属性映射到应用程序更新的 ZIP 存档。对象中的所有其他属性都是可选的。

https://your-deployment-url.com/update/darwin/0.31.0
{
"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 响应。