Skip to main content

更新应用

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

¥There are several ways to provide automatic updates to your Electron application. The easiest and officially supported one is taking advantage of the built-in Squirrel framework and Electron's autoUpdater module.

使用 update. Electronjs.org

¥Using update.electronjs.org

Electron 团队维护 update.electronjs.org,这是一个免费的开源 Web 服务,Electron 应用可以使用它进行自我更新。该服务专为满足以下条件的 Electron 应用而设计:

¥The Electron team maintains update.electronjs.org, a free and open-source webservice that Electron apps can use to self-update. The service is designed for Electron apps that meet the following criteria:

  • 应用在 macOS 或 Windows 上运行

    ¥App runs on macOS or Windows

  • 应用有一个公共 GitHub 存储库

    ¥App has a public GitHub repository

  • 版本发布到 GitHub 发布

    ¥Builds are published to GitHub Releases

  • 版本为 code-signed

    ¥Builds are code-signed

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

¥The easiest way to use this service is by installing update-electron-app, a Node.js module preconfigured for use with update.electronjs.org.

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

¥Install the module using your Node.js package manager of choice:

npm install update-electron-app

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

¥Then, invoke the updater from your app's main process file:

main.js
require('update-electron-app')()

默认情况下,此模块将在应用启动时检查更新,然后每十分钟检查一次。当发现更新时,它将在后台自动下载。下载完成后,将显示一个对话框,允许用户重新启动应用。

¥By default, this module will check for updates at app startup, then every ten minutes. When an update is found, it will automatically be downloaded in the background. When the download completes, a dialog is displayed allowing the user to restart the app.

如果你需要自定义配置,可以选择 将选项传递给 update-electron-app直接使用更新服务

¥If you need to customize your configuration, you can pass options to update-electron-app or use the update service directly.

使用其他更新服务

¥Using other update services

如果你正在开发私有 Electron 应用,或者你不将版本发布到 GitHub Releases,则可能需要运行你自己的更新服务器。

¥If you're developing a private Electron application, or if you're not publishing releases to GitHub Releases, it may be necessary to run your own update server.

步骤 1:部署更新服务器

¥Step 1: Deploying an update server

根据你的需要,你可以选择以下之一:

¥Depending on your needs, you can choose from one of these:

  • Hazel - 更新可在 Vercel 上免费部署的私有或开源应用的服务器。它源自 GitHub 发布 并利用 GitHub 的 CDN 的强大功能。

    ¥Hazel – Update server for private or open-source apps which can be deployed for free on Vercel. It pulls from GitHub Releases and leverages the power of GitHub's CDN.

  • 坚果 - 也使用 GitHub 发布,但在磁盘上缓存应用更新并支持私有存储库。

    ¥Nuts – Also uses GitHub Releases, but caches app updates on disk and supports private repositories.

  • electron-release-server - 提供用于处理发布的仪表板,并且不需要发布源自 GitHub。

    ¥electron-release-server – Provides a dashboard for handling releases and does not require releases to originate on GitHub.

  • - 由 Atlassian 维护的 Electron 应用的完整更新服务器。支持多种应用和渠道;使用静态文件存储来降低服务器成本。

    ¥Nucleus – A complete update server for Electron apps maintained by Atlassian. Supports multiple applications and channels; uses a static file store to minify server cost.

部署更新服务器后,你可以检测应用代码以使用 Electron 的 autoUpdater 模块接收和应用更新。

¥Once you've deployed your update server, you can instrument your app code to receive and apply the updates with Electron's autoUpdater module.

步骤 2:在你的应用中接收更新

¥Step 2: Receiving updates in your app

首先,在主进程代码中导入所需的模块。以下代码可能因不同的服务器软件而异,但其工作原理与使用 Hazel 时所描述的相同。

¥First, import the required modules in your main process code. The following code might vary for different server software, but it works like described when using Hazel.

检查你的执行环境!

请确保以下代码仅在你的打包应用中执行,而不是在开发中执行。你可以使用 app.isPackaged API 检查环境。

¥Please ensure that the code below will only be executed in your packaged app, and not in development. You can use the app.isPackaged API to check the environment.

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

接下来,构建更新服务器源的 URL 并告知 autoUpdater

¥Next, construct the URL of the update server feed and tell autoUpdater about it:

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

autoUpdater.setFeedURL({ url })

最后一步,检查更新。下面的示例将每分钟检查一次:

¥As the final step, check for updates. The example below will check every minute:

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

一旦你的应用达到 packaged,它将收到你发布的每个新 GitHub 发布 的更新。

¥Once your application is packaged, it will receive an update for each new GitHub Release that you publish.

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

¥Step 3: Notifying users when updates are available

现在你已经为应用配置了基本更新机制,你需要确保用户在有更新时收到通知。这可以使用 自动更新 API 事件 来实现:

¥Now that you've configured the basic update mechanism for your application, you need to ensure that the user will get notified when there's an update. This can be achieved using the autoUpdater API events:

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 的示例:

¥Also make sure that errors are being handled. Here's an example for logging them to stderr:

main.js
autoUpdater.on('error', (message) => {
console.error('There was a problem updating the application')
console.error(message)
})
手动处理更新

由于 autoUpdate 发出的请求不受你的直接控制,因此你可能会发现难以处理的情况(例如更新服务器落后于身份验证)。url 字段支持 file:// 协议,这意味着通过一些努力,你可以通过从本地目录加载更新来避开该过程的服务器通信方面。这是一个如何运作的示例

¥Because the requests made by autoUpdate aren't under your direct control, you may find situations that are difficult to handle (such as if the update server is behind authentication). The url field supports the file:// protocol, which means that with some effort, you can sidestep the server-communication aspect of the process by loading your update from a local directory. Here's an example of how this could work.