跳到主要內容

更新應用程式

有多種方式可以為您的 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 回應。