@masrobo/electron-custom-updater
v1.0.0
Published
桌面端自定义更新器:JSON 清单(版本+md5)检测 + NSIS 就地安装(参考 electron-updater)。源为 TS,由 Vite 构建的 Electron 主进程直接打包。
Maintainers
Readme
electron-custom-updater
桌面端自定义更新器。参考官方 electron-updater 的 API 与就地更新机制,但保留自有的 JSON 清单 + 版本/md5 检测,不引入 electron-builder 发布体系。源为 TypeScript,由 Vite 构建的 Electron 主进程直接打包。
设计总览
检测(保留自有方案) 安装(参考 electron-updater)
┌────────────────────────────┐ ┌────────────────────────────────┐
│ COS JSON 清单(version+md5) │ │ Windows: 直接 spawn │
│ 版本比对 / appMd5 比对 │ ───▶ │ Setup.exe /S /D=<安装目录> │
└────────────────────────────┘ │ --force-run │
│ EACCES 时 elevate.exe 提权重试 │
│ macOS/Linux: 便携目录+current.txt│
└────────────────────────────────┘安装
npm i @masrobo/electron-custom-updater使用
import { autoUpdater } from '@masrobo/electron-custom-updater'
// 项目专属配置必须显式传入(appName / executableName / manifestName 各项目不同)
autoUpdater.setFeedURL({
feedUrl: 'https://bucket.cos.region.myqcloud.com', // COS bucket 根
manifestName: '<app>/release/version.json', // 相对 bucket 根
appName: 'MyApp', // 便携目录名(mac/linux)
executableName: 'my-app', // 可执行文件名(不含 .exe)
})
const r = await autoUpdater.checkForUpdates() // { hasUpdate, remoteVersion, artifact }
if (r.hasUpdate) {
const dl = await autoUpdater.downloadUpdate() // md5 校验 + 竞态重试
if (dl.ok) autoUpdater.quitAndInstall() // Windows 就地安装 + 重启
}
autoUpdater.onStatus((s) => /* checking/downloading/installed/error */)
autoUpdater.onProgress((p) => /* 进度 */)云存储(COS)文件路径结构(必读)
清单路径与产物路径均相对 bucket 根,格式如下(<app> 为应用发布目录名,<App> 为产品名,<version> 形如 v0.9.2):
<bucket>/
└── <app>/release/
├── version.json # 顶层清单
└── v<version>/ # 例如 v0.9.2
├── win.json # 平台清单(win32 用)
├── linux.json
├── mac.json
└── win/ # 安装包/压缩包
├── <App> Setup <version> x64.exe # Windows NSIS 安装包(更新用,必传)
└── <App>-win32-x64.zip # 便携包(mac/linux 更新用)version.json(顶层)
{
"version": "v0.9.2",
"win": "<app>/release/v0.9.2/win.json",
"linux": "<app>/release/v0.9.2/linux.json",
"mac": "<app>/release/v0.9.2/mac.json"
}win.json(平台清单)
{
"version": "v0.9.2",
"platform": "win",
"appMd5": "<md5 of resources/app.asar>",
"artifacts": [
{
"name": "<App> Setup v0.9.2 x64.exe",
"path": "<app>/release/v0.9.2/win/<App> Setup v0.9.2 x64.exe",
"size": 108000000,
"md5": "<安装包 md5>"
}
]
}appMd5:本机resources/app.asar的 md5,一次比对覆盖「版本相同、内容变更」与「版本不同」两个场景。- Windows 更新优先选
.exe安装包;mac/linux 选 zip/tar.gz。 - 清单由发布脚本生成(
win.json+version.json)。
更新检测
判定(detection.ts,纯函数):
- 版本相同 + appMd5 相同 → 无更新
- 版本相同 + appMd5 不同(同版本内容重建)→ 有更新
- 版本不同 → 有更新(兼做 remote.appMd5 缺失兜底)
安装(Windows 就地更新)
- 下载 NSIS Setup(.exe) → 校验 md5(不匹配时重取清单用新 md5 重试一次)。
- 点「立即重启」时直接 spawn 安装包(GUI 子系统进程,spawn 后可脱离父进程存活):
Setup.exe /S /D=<当前安装目录> --force-run/S静默安装到/D=指定目录(支持自定义安装路径)。--force-run:安装完成后安装器自动重启应用。- ⚠️ 不要用
--updated:实测部分 electron-builder NSIS fork 安装器的--updated更新模式会清空安装目录但不装新文件。 - 权限不足(EACCES/UNKNOWN)时用
resources/elevate.exe提权重试(构建需nsis.packElevateHelper: true);ENOENT 时交给系统打开。
- spawn 后
setImmediate(() => app.quit())。
macOS/Linux:下载 zip/tar.gz → 解压到便携目录(appName 命名)+ current.txt 指针 → 重启。
为什么直接 spawn 安装包而不是 schtasks / spawn 控制台进程
实测:Windows 上 spawn('powershell.exe'/'cmd.exe', …, {detached:true}) 的控制台子进程不会执行命令;但 NSIS 安装包是 GUI 子系统进程,spawn 后能脱离父进程独立执行——这是 electron-updater 的做法,比 schtasks 更简单,也无需依赖 VBScript(Win11 24H2+ 已按需化、微软计划移除)。
目录结构
electron-custom-updater/
├── package.json # name: electron-custom-updater(main: src/index.ts,TS 源)
└── src/
├── index.ts # autoUpdater 主 API:setFeedURL / checkForUpdates / downloadUpdate / quitAndInstall + 事件
├── config.ts # 更新源配置(feedUrl / manifestName / appName / executableName / platformKey)
├── manifest.ts # 拉取 COS JSON 清单(version.json → <platform>.json)+ 选可安装产物
├── detection.ts # 更新判定(版本 + appMd5)+ 本机 app.asar md5
├── download.ts # 下载 + md5 校验 + 「发布窗口竞态」重取清单用新 md5 重试一次
├── install.ts # Windows:直接 spawn Setup /S /D= --force-run;macOS/Linux:便携目录解压
└── types.ts # 公共类型(含 CustomUpdaterConfig)与官方 electron-updater 的取舍
- 保留:JSON 清单(版本+md5)检测、COS 直传、无 electron-builder publish 体系依赖。
- 参考:autoUpdater API 形态、NSIS
/S /D= --force-run就地安装。 - 未采用:electron-builder
latest.yml/差分更新(本方案为整包下载,无 .blockmap);代码签名校验(publisherName)未启用。
