electron-update-sdk
v1.3.1
Published
Reusable Electron update checking and installation SDK
Maintainers
Readme
electron-update-sdk
统一管理 Electron 应用更新和 ZIP 网页资源更新。检查、来源回退、下载、取消、缓存、校验及状态在 SDK 内完成;应用只配置来源、存储和生命周期,资源生效后由应用切换页面。Aurora Plus 的 AuUpdateDialog 只负责展示与用户操作。
应用更新
import path from 'node:path';
import { app, ipcMain, BrowserWindow } from 'electron';
import {
ElectronUpdateClient,
UpdateSourceFactory,
createUpdateLogger,
createFileSkippedVersionStore,
} from 'electron-update-sdk';
import { bindUpdateIpc } from 'electron-update-sdk/ipc';
const updates = new ElectronUpdateClient({
currentVersion: () => app.getVersion(),
sources: [
UpdateSourceFactory.github({ owner: 'owner', repository: 'release-repository' }),
UpdateSourceFactory.gitee({ owner: 'owner', repository: 'release-repository' }),
],
skippedVersionStore: createFileSkippedVersionStore({
filePath: path.join(app.getPath('userData'), 'updates.json'),
}),
runtime: { forceDevelopmentUpdates: () => !app.isPackaged },
logger: createUpdateLogger({ directoryProvider: () => app.getPath('logs') }),
});
const releaseIpc = bindUpdateIpc({
ipcMain,
client: updates,
channel: 'app-update',
authorize: (event) => Boolean(BrowserWindow.fromWebContents(event.sender)),
recipients: () => BrowserWindow.getAllWindows().map((window) => window.webContents),
});
app.whenReady().then(() => updates.start());
// 应用退出时调用 releaseIpc(),并在自己的退出流程中等待 updates.dispose()。所有来源并行预检,按配置顺序确认较新版本;来源失败时继续下一个候选。下载锁定检查确认的 provider,保留差分下载与整包回退。Gitee provider 复用预检的 Release 和附件列表,避免重复 API 请求。
GitHub 公开仓库固定读取最新正式 Release 的 latest.yml 附件,不调用 GitHub REST API,也无需配置元数据策略。安装包和差分文件仍由公开 GitHub provider 下载。来源地址、请求头及 provider 对象不进入公开快照。
| 方法 | 行为 |
| ------------------------------- | -------------------------------------------------- |
| initialize() | 幂等初始化,失败允许重试 |
| start({ delayMs = 2000 }) | 安排一次启动检查,重复调用不重复安排 |
| check({ trigger = 'manual' }) | 检查更新,并发检查共用任务 |
| download() | 下载已确认版本,并发下载共用任务 |
| cancel() | 取消下载,等待任务及缓存清理结束 |
| skipVersion(version) | 保存跳过版本并发布无更新状态 |
| install() | 刷新日志,退出并安装,并发安装共用任务 |
| getSnapshot() | 获取独立、可序列化的状态副本 |
| subscribeState(listener) | 订阅完整快照,返回取消订阅函数 |
| dispose() | 停止启动计时器、请求与订阅,等待下载清理及日志刷新 |
操作结果使用 { ok, state?, files?, error? }。任务失败同时发布 error 状态;初始化、安装异常由 IPC 适配器转换为失败结果。应用更新检查可以在关闭对话框后继续,下载取消会等待清理完成。
元数据使用 Fetch,可通过 network.fetch 注入。network.metadataTimeoutMs 与 timeouts.checkMs 默认 15000。Windows 差分下载前清除不能确认归属的 current.blockmap,保留当前版本安装包并从确认来源获取 blockmap。
ZIP 资源更新
import path from 'node:path';
import { app } from 'electron';
import { ResourceUpdateClient } from 'electron-update-sdk';
const resources = new ResourceUpdateClient({
storageRoot: path.join(app.getPath('userData'), 'web_dist'),
source: {
id: 'web-resources',
name: '网页资源服务',
indexUrl: 'https://example.com/updates/latest.json',
downloadBaseUrl: 'https://example.com/updates/packages/',
},
async onApplied({ directory, version }) {
// 在此切换本地资源服务的目录并刷新页面。
console.log('资源已生效', version, directory);
},
});
await resources.initialize();
if (!resources.activeVersion) await resources.prepare({ apply: true });索引格式为 { version, releaseNotes?, package: { downloadUrl, sha256, size? } }。SDK 自带 Fetch 下载和 ZIP 读取,应用无需提供请求函数或解压库。
手动检查、下载和取消使用相同的 check()、download()、cancel()、getSnapshot()、subscribeState()。资源下载包含应用步骤,没有单独的 install() 或 skipVersion()。activeVersion 与 activeDirectory() 提供当前资源位置。
prepare()后台下载,记录 pending 版本,下次初始化生效,保留当前页面与手动对话框状态。prepare({ apply: true })首次准备并激活资源,不调用页面切换回调。download()锁定手动检查确认的索引,激活后调用onApplied;回调失败可重试。- 手动与后台任务串行写入目录。手动取消不影响后台任务;进入安装后取消等待提交和页面切换结束;退出取消所有资源请求并等待目录操作结束。
校验链为可信 HTTPS 下载目录 → SHA-256 → 安全版本目录 → 防 Zip Slip → 根目录 index.html → 完整目录提交。失败会清理临时解压目录。版本按 semver 比较,使用 major.minor.patch 格式,支持 v 前缀、预发布标识与构建信息。
可选 network.fetch 注入请求实现,network.metadataTimeoutMs 默认 30000,ZIP 下载不限时且支持取消。特殊运行环境可注入 readArchive(bytes)(返回含 entryName/isDirectory/getData() 的条目)或 compareVersions;安全校验仍由 SDK 执行。source.enabled: false 禁用资源更新。
IPC 与 Vue 接入
主进程使用 bindUpdateIpc,preload 使用同一个频道创建 transport:
import { contextBridge, ipcRenderer } from 'electron';
import { createUpdateTransport } from 'electron-update-sdk/ipc';
contextBridge.exposeInMainWorld(
'applicationUpdates',
createUpdateTransport(ipcRenderer, { channel: 'app-update' }),
);<script setup>
import { ref } from 'vue';
import { AuButton, AuUpdateDialog } from 'aurora-plus';
import { useUpdateDialog } from 'electron-update-sdk/vue';
const visible = ref(false);
const update = useUpdateDialog({
visible,
autoOpen: true,
transport: window.applicationUpdates,
});
</script>
<template>
<AuButton @click="visible = true">检查更新</AuButton>
<AuUpdateDialog
v-model="visible"
v-bind="update.dialogProps.value"
v-on="update.dialogEvents"
app-name="Example"
show-skip
/>
</template>资源更新在主进程和 preload 都配置 kind: 'resources',使用独立频道(如 resource-update),不显示跳过版本按钮。bindUpdateIpc 返回清理函数;client 可传实例或返回实例的函数,供资源运行时重建后自动切换。调用者必须提供 authorize(event, method) 与 recipients(),保持应用原有的页面权限隔离。
transport 直接传 SDK 创建的对象,包含 getSnapshot/subscribeState/check/download/cancel,应用更新额外包含 install/skipVersion,无需逐个包装函数。subscribeState 返回取消订阅函数。已有独立通信层也可实现同一接口。
Vue 适配器负责恢复快照、拒绝迟到状态、重试、取消与显示数据转换;关闭下载对话框会取消下载,卸载时解除订阅。autoOpen 默认 false,开启后提示发现更新、下载完成及下载失败;主动关闭抑制本次后续提示。
返回 state(只读)、dialogProps、dialogEvents 与 releaseNotes。可配置 formatSize(bytes)、formatNotes(notes)、onAvailable()、onClose()。
状态与配置
快照包含 status/currentVersion/info/progress/source/sources/errorStage/message,资源更新还提供 description/progressText。来源列表只包含显示名称、状态、版本及公开错误文案。
状态为 idle/checking/available/not-available/downloading/downloaded/installing/cancelled/error;Vue 将 not-available 映射为 latest、downloaded 映射为 ready。
skippedVersionStore: { read, write }可复用应用已有存储;也可使用createFileSkippedVersionStore({ filePath })。createUpdateLogger({ directoryProvider, fileName, maxBytes, retainedFiles, consoleTarget, formatMessage })提供滚动日志和flush();默认文件名 updater.log、2 MB、保留 3 份。- Client 的
formatError(error)和 IPC 的formatError(error)统一转换公开错误,日志可用formatMessage脱敏。
目录职责
| 目录 | 职责 |
| ---------------------- | ---------------------------------------------------------------- |
| src/app-update/ | 应用检查与回退、下载取消、差分缓存、跳过版本与 Electron 生命周期 |
| src/resource-update/ | 资源任务、版本指针、ZIP 校验及提交 |
| src/release/ | 来源配置、Release 元数据、Gitee provider |
| src/network/ | 共享 Fetch 请求、响应读取、超时与取消 |
| src/state/ | 共享状态、快照、错误格式与订阅 |
| src/ipc/ | 通用主进程命令注册与 preload transport |
| src/vue/ | 对话框属性、事件及快照恢复 |
| src/shared/ | 日志、参数校验、URL 模板与版本适配 |
源码使用 kebab-case 文件名。应用只从包入口、/ipc、/vue 导入,避免依赖内部路径。主入口用于 Node/Electron;/ipc 不加载 Electron,/vue 不加载主进程模块。Vue 是可选 peer dependency。
Node.js 最低 18.17。SDK 固定依赖 electron-updater 6.8.9、adm-zip 0.5.18,以及更新器依赖树中已有的 js-yaml 4.3.1、semver 7.7.4;应用无需重复声明这些更新依赖。
本次迁移
旧的逐方法 IPC 包装改为 bindUpdateIpc/createUpdateTransport。Vue transport 的 subscribe 改为 subscribeState,cancelCheck/cancelDownload 合并为 cancel;ElectronUpdateClient.cancelDownload() 改为 cancel()。资源客户端不再要求注入 requestBinary 或 readArchive。
GitHub 更新源移除 metadataStrategy 与 apiBaseUrl 配置,统一读取 latest.yml 附件;调用者删除这两个参数即可。Gitee 的 apiBaseUrl 继续支持。
