可自行更新的 Wails 應用程式
建置可透過 GitHub Releases 自行更新的 Wails v3應用程式——涵蓋從`wails3 init`、已簽署版本驗證到輔助程式模式置換的完整流程。
在本教學中,你將為全新的 Wails v3應用程式加入應用程式內更新程式。完成後,應用程式將能:
- 依需求檢查 GitHub Releases(也可選擇透過計時器定期檢查)。
- 下載適用於目前執行中作業系統與架構的資產。
- 根據下載的位元組驗證 SHA-256摘要(也可選擇驗證 Ed25519 簽章)。
- 在框架的預設更新視窗中顯示版本資訊。
- 置換執行中的二進位檔並重新啟動,完全不必隨附個別的輔助執行檔。
我們將使用GitHub Releases作為更新來源,因為它免費且不需要任何基礎架構。同樣的模式也適用於keygen.sh和Sparkle AppCast。完成後,請參閱更新程式指南。
從全新的 Wails 應用程式開始
使用 vanilla 範本建立新專案的骨架:
wails3 init -n updater-tutorial -t vanilla
cd updater-tutorial
現在應該會有一個包含main.go、frontend/和Taskfile.yml的目錄。確認專案可以建置並啟動:
wails3 task dev
此時應開啟一個空白的 Wails 視窗。結束應用程式後繼續。
加入更新程式的匯入項目
開啟main.go,並將兩個更新程式套件加入匯入項目:
package main
import (
_ "embed"
"github.com/wailsapp/wails/v3/pkg/application"
"github.com/wailsapp/wails/v3/pkg/updater"
"github.com/wailsapp/wails/v3/pkg/updater/providers/github"
)這些套件會引入 Updater 本身及 GitHub Releases 提供者。
設定 Updater
每個*application.App都已接好app.Updater,你只需呼叫Init:
const currentVersion = "1.0.0"
gh, err := github.New(github.Config{
Repository: "yourorg/your-repo", // ← change this
ChecksumAsset: "SHA256SUMS", // sibling file with sha256 digests
})
if err != nil {
log.Fatalf("github.New: %v", err)
}
if err := app.Updater.Init(updater.Config{
CurrentVersion: currentVersion,
Providers: []updater.Provider{gh},
}); err != nil {
log.Fatalf("Updater.Init: %v", err)
}將此程式碼放在application.New之後、app.Run()之前。
加入觸發更新的選單項目
在同一個main.go中加入「檢查更新…」選單項目:
menu := app.Menu.New()
app.Menu.SetApplicationMenu(menu)
appMenu := menu.AddSubmenu("App")
appMenu.Add("Check for Updates…").OnClick(func(*application.Context) {
go func() {
if err := app.Updater.CheckAndInstall(context.Background()); err != nil {
app.Logger.Error("update", "error", err)
}
}()
})CheckAndInstall會開啟框架的更新視窗、執行Check,若找到發行版本,則自動執行DownloadAndInstall。沒有新版本時,視窗會停留在「已是最新版本」狀態,由使用者按下關閉按鈕將其關閉。
在沒有發行版本的情況下執行一次
wails3 task dev
按一下App → 檢查更新…。更新視窗應會短暫開啟、呼叫 GitHub API、找不到比1.0.0更新的發行版本,最後停留在帶有綠色 ✓ 的已是最新版本狀態。
如果此處發生錯誤,通常是以下原因之一:
| 症狀 | 修正方式 |
|---|---|
404 Not Found |
Repository欄位不正確——必須是owner/repo |
403 rate-limited |
將Token: "ghp_…"加入 github.Config(使用具備public_repo範圍的 PAT) |
| 網路錯誤 | 確認執行中的應用程式可以連線至api.github.com |
發布測試用發行版本
將main.go中的currentVersion遞增至1.0.0(或維持不變)。針對一個平台進行建置,以取得可附加至發行版本的二進位檔:
wails3 task build:darwin
# produces bin/updater-tutorial.app
# zip it for the release asset:
cd bin && zip -r updater-tutorial-darwin-arm64.zip updater-tutorial.app && cd ..
wails3 task build:linux
# produces bin/updater-tutorial
mv bin/updater-tutorial bin/updater-tutorial-linux-amd64
wails3 task build:windows
# produces bin/updater-tutorial.exe
mv bin/updater-tutorial.exe bin/updater-tutorial-windows-amd64.exe
在二進位檔旁產生一個SHA256SUMS檔案:
cd bin
shasum -a 256 updater-tutorial-* > SHA256SUMS
cat SHA256SUMS
你應該會看到一或多行類似以下的內容:
abc123… updater-tutorial-darwin-arm64.zip現在將其作為v2.0.0發布至你的 GitHub 儲存庫:
gh release create v2.0.0 \
--title "v2.0.0" \
--notes "First update for the self-update tutorial.
- **Bold** Markdown renders in the update window
- \`Code spans\` too
- Lists work
- GFM tables work" \
bin/SHA256SUMS bin/updater-tutorial-*
執行應用程式並驗證更新
在currentVersion仍為1.0.0時,再次執行應用程式:
wails3 task dev
按一下App → 檢查更新…。這次應該會看到類似以下的內容:

- 主圖示會從藍色 ↓(「有可用更新」)變成綠色 ✓(「更新已就緒」)。
- 副標題顯示
v1.0.0 → v2.0.0 · <size>。 - 版本資訊面板會轉譯你的 Markdown,包括粗體、行內程式碼和表格。
- 下載期間進度列會逐漸填滿(二進位檔很小,因此速度會很快)。
Updater 會將新的二進位檔暫存於臨時目錄。若要完成更新:
- 按一下重新啟動並套用。
- 應用程式會結束,輔助程式會置換二進位檔,接著重新啟動新的二進位檔。
- 重新啟動的應用程式會回報
currentVersion = "1.0.0"(因為我們將它寫死了),但磁碟上的位元組與v2.0.0組建相符。
在實際的應用程式中,currentVersion會在建置時透過-ldflags設定,使新的二進位檔知道自己目前是v2.0.0,而後續檢查也不會找到更新。
將`currentVersion`連結至建置流程
將常數替換為建置時變數:
var (
currentVersion = "dev" // overridden by -ldflags at release time
)接著在建置命令中:
wails3 task build:darwin -- -ldflags "-X main.currentVersion=2.0.0"
或者,將-ldflags加入Taskfile.yml,使其從git describe --tags取得值。
加入密碼學簽章(建議用於正式環境)
SHA256SUMS 路徑會驗證完整性(位元組與 GitHub 所儲存的內容相符),但不會驗證真實性(亦即這些位元組是由你的發行流程產生,而不是來自遭入侵的維護者帳號)。為了防止竄改,請使用 Ed25519 金鑰簽署每個發行版本:
# One-time: generate the keypair
ssh-keygen -t ed25519 -f updater-key -N "" -C "wails-updater"
# updater-key — keep secret (build server, HSM, password manager)
# updater-key.pub — bundle in your app
每次發行時,請使用私鑰簽署每個資產的 SHA-256 摘要。以下是一個小型 Go 輔助程式:
package main
import (
"crypto/ed25519"
"crypto/sha256"
"encoding/base64"
"fmt"
"io"
"os"
)
func main() {
priv, _ := os.ReadFile("updater-key")
key := ed25519.PrivateKey(priv) // raw 64-byte private key
f, _ := os.Open(os.Args[1])
defer f.Close()
h := sha256.New()
_, _ = io.Copy(h, f)
sig := ed25519.Sign(key, h.Sum(nil))
fmt.Println(base64.StdEncoding.EncodeToString(sig))
}預設的 GitHub 提供者目前不會擷取個別的簽章檔案;你可以撰寫自訂提供者來擷取,或改用 keygen.sh。後者會在伺服器端簽署每個成品,並透過其 API 提供摘要與簽章。
將公開金鑰嵌入你的應用程式:
//go:embed updater-key.pub
var updaterPublicKey []byte
app.Updater.Init(updater.Config{
CurrentVersion: currentVersion,
PublicKey: updaterPublicKey,
Providers: []updater.Provider{gh},
})設定PublicKey後,任何附帶Signature的發行版本都必須通過此金鑰的驗證。發行來源無法替換成自己的金鑰;這正是在建置時透過頻外方式固定金鑰的目的。
自訂視窗
預設視窗適用於常見情境。如果需要更多控制,可依照你想自訂的程度,從以下三種方式中選擇一種:
app.Updater.Init(updater.Config{
// …
Window: &updater.BuiltinWindow{
CSS: `:root { --accent: #ff6f00; --radius: 16px; }`,
},
})如需完整的變數清單,請參閱透過 CSS 變數設定主題一節。
//go:embed updater-window.html
var updaterHTML string
app.Updater.Init(updater.Config{
// …
Window: &updater.BuiltinWindow{HTML: updaterHTML},
})你的 HTML 必須訂閱updater:*事件,並透過 Wails 事件通道發出updater:user:*動作。如需 JS 轉接程式,請參閱替換範本。
myWin := app.Window.NewWithOptions(application.WebviewWindowOptions{
Title: "My App Updater",
Width: 520, Height: 460,
HTML: updaterHTML,
AllowSimpleEventEmit: true, // required — see security note
})
app.Updater.Init(updater.Config{
// …
Window: updater.BYOWindow(myWin.AsUpdaterWindow()),
})如果你已有自己的視窗基礎架構,並希望更新程式驅動該視窗,而不是另開一個視窗,這種方式會很實用。以下是一個完全自訂的 HTML 範本,由與預設範本相同的更新程式事件驅動:

在背景執行自動檢查
若要依計時器檢查,而不是透過選單點擊來檢查(或兩者並用):
app.Updater.Init(updater.Config{
CurrentVersion: currentVersion,
Providers: []updater.Provider{gh},
PublicKey: updaterPublicKey,
CheckInterval: 6 * time.Hour,
})每次計時器觸發時,都會執行與手動點擊相同的CheckAndInstall流程。如果你希望定期檢查在實際找到更新前保持靜默,請設定Window: updater.WindowNone,然後自行訂閱EventUpdateAvailable,以決定要顯示何種使用者體驗。
大功告成
你現在已有一個具備以下功能的 Wails 應用程式:
- 可依需求或按照計時器檢查 GitHub Releases 中的更新。
- 在精美的預設視窗中將版本資訊呈現為 Markdown。
- 使用你發布的 SHA-256 摘要驗證下載內容。
- 可選擇使用建置時嵌入的公開金鑰來驗證 Ed25519 簽章。
- 原地替換執行中的二進位檔,並自動重新啟動。
後續步驟
- 更新程式指南包含完整的 API 參考、所有事件、所有設定選項,以及輔助模式的替換機制。
- 請查看
v3/examples/updater,其中提供可供複製的完整運作範例。 - 測試目標儲存庫
wailsapp/updater-demo展示了建議的發行資產配置。
正式環境中的注意事項
- macOS 上的程式碼簽署 — Gatekeeper 要求替換後的二進位檔必須經過簽署與公證。在將
.app套件壓縮成發行用 zip 檔之前,請先簽署套件。更新程式會逐位元組原樣保留內容,不會重新簽署任何項目。 - Windows 上的防毒軟體 — 從網際網路下載且未簽署的
.exe檔案可能會觸發 SmartScreen 警告。請使用 Authenticode 憑證簽署二進位檔,否則必須接受使用受嚴格管控之電腦的使用者可能需要將你的應用程式加入允許清單。 - 不可分割的發行作業 — 請一起發布
SHA256SUMS與二進位檔,不要分成不同的提交。更新程式會分別擷取附屬檔案與二進位檔;若兩者不同步,摘要檢查將以失敗方式安全終止。 - 略過的版本 — 預設視窗中的「略過此版本」按鈕會將略過設定記錄在本機。如果發布重大安全性更新,請使用新的版本號碼,以免先前略過某個發行版本的使用者也自動略過此更新。