Electron 中 自动更新


前言

对前置的构建产物,是有要求的:

  • latest-mac.ymllatest.yml 文件, 用于记录版本信息, 里面包含要下载的文件
  • Mac 下要有 .zip
  • Windows 下要有 .exe

上架应用市场的

比如 MAS 的,软件自身是不提供自动更新的,需要屏蔽, 让更新交给平台管理。

全量更新

electron 内置了 autoUpdater | Electron 模块,用来实现全量更新。

Mac 下,还有个工具,集成了 sparkle-project/Sparkle: A software update framework for macOS, 这个原生程序更新框架,Hydraulic

实现原理

electron 内置了 Squirrel 相关包,用于拉取并做更新安装。在 windows 中,electron-builder 构建的安装的程序中,会有一个elevate.exe, 用于提权安装。

流程:

  • autoUpdater.setFeedURL() 设置更新的地址
  • autoUpdater.checkForUpdates() 检查更新
  • 自动下载到各平台对应目录,然后执行 Squirrel 相关的命令,完成更新。
    • Mac 是 ~/Library/Application Support/Caches/<app_name>-updater 目录,下载的是 .zip
    • Windows 是 C:\Users\username\AppData\Local\<app_name>-updater 目录,下载的是 .exe 包, 这一层还有一个 install.exe , 可能是负责单独更新的吧
  • autoUpdater.quitAndInstall 退出并安装, 这一步应该能知道软件的安装位置, 不然就无法更新了把

但实际使用, 比如 erb 中,使用了 electron-updater 包,对上述又做了封装。

免费的服务端方案

electron 为开源的项目, 提供了 update.electronjs.org 服务, 可以免费使用。

forge 配置

erb 配置

Auto Update | Electron React Boilerplate, 主要实现逻辑还是 Auto Update - electron-builder

  • 如果本身就是开源项目,默认就是上传 github 的
  • 添加 electron-updater 这个包。他应该是再包装了 autoUpdater 模块。

是否可以自定义安装路径

如果安装到了有权限的目录后,能够自动更新吗?

要试试

asar 包更新

比如 VSC 那样, 好像就是下载了一个 asar 包, 然后替换了原来的 asar 包。

win 下几种安装包类型

主要是 Squirrel.WindowsNSIS 的区别, MSI 是另外最简单的一种压缩包的形式。

  • Squirrel.Windows 强调静默安装, 和 Electron 集成更好
  • NSIS 自定义特性强
Squirrel.Windows 和 NSIS(Nullsoft Scriptable Install System)都是用于创建 Windows 应用程序安装程序的工具,但它们在设计理念、功能和使用方式上有一些显著的区别:

1. **设计理念**:
   - **Squirrel.Windows**:专为简化现代桌面应用程序(尤其是基于 Electron 的应用程序)的安装和更新过程而设计。它重点关注简单性和自动更新功能。
   - **NSIS**:是一个更传统、更通用的安装程序制作工具,允许高度定制安装过程。它适用于各种类型的 Windows 应用程序,提供了强大的脚本能力来控制安装逻辑。

2. **功能特点**:
   - **Squirrel.Windows**:自动处理安装、更新、创建和删除快捷方式等任务。它支持静默安装,通常不需要用户交互,并且能够处理应用程序的自动更新。
   - **NSIS**:通过脚本来定义安装逻辑,可以创建复杂的安装界面和定制的安装过程。它提供了丰富的插件和扩展功能。

3. **集成和使用**:
   - **Squirrel.Windows**:与 Electron 紧密集成,特别适合 Electron 应用程序。使用时相对简单,大多数情况下无需复杂配置。
   - **NSIS**:需要编写安装脚本来定义安装行为。虽然它的灵活性高,但也意味着需要更多的定制工作。它可以用于各种不同类型的应用程序,不限于 Electron。

4. **更新机制**:
   - **Squirrel.Windows**:内置了自动更新机制,使得应用程序可以在后台检查和安装更新,为用户提供无缝更新体验。
   - **NSIS**:本身不提供内置的自动更新机制,需要开发者自行实现更新逻辑或集成其他工具。

总结来说,Squirrel.Windows 更侧重于简化和自动化 Electron 应用程序的安装和更新,而 NSIS 提供了更多的灵活性和定制能力,适用于需要详细控制安装过程的各种应用程序。根据应用程序的具体需求和开发者的偏好来选择合适的工具。

win 自动更新原理

nsis 包

electron-builder/packages/electron-updater/src/NsisUpdater.ts at 869c7e4652a5d5a3562e25723d6cedd622ab657b · electron-userland/electron-builder

内置了 elevate.exe, 然后提权安装。

squirrel 包

autoUpdater | Electron 自带的。

Mac 自动更新原理

autoUpdater | Electron

内置的 autoUpdater 模块,基于 Squirrel.Mac 的更新方案。forgeelectron-builder 都是这样。

读取 latest-mac.yml 的逻辑在这里: electron-builder/packages/electron-updater/src/MacUpdater.ts at master · electron-userland/electron-builder, 优先获取 zip 文件, 并且自动找 arm64 的文件, 解压,最后调用 nativeUpdater.quitAndInstall

  • 判断宿主环境是否 arm64, 然后从 files 中过滤包含 arm64 的文件, 取 zip 的使用
  • 如果是 intel, 就是取不包含 arm64 的文件, 取 zip 的使用
  • latest-mac.yml 只使用到 files 字段,和 path 字段无关

blockmap 文件

What is the purpose of blockmap file? · Issue #2851 · electron-userland/electron-builder

没找到出处, 但是应该是用来做增量更新的。是用于增量下载什么呢?

可以被禁用掉, Remove Block Map · Issue #2900 · electron-userland/electron-builder

开发环境测试

Auto Update - electron-builder

Note that in order to develop/test UI/UX of updating without packaging the application you need to have a file named dev-app-update.yml in the root of your project, which matches your publish setting from electron-builder config (but in yaml format). But it is not recommended, better to test auto-update for installed application (especially on Windows). Minio is recommended as a local server for testing updates.

开发阶段,是没有 packaged 的, 测试自动更新,无法完成 install 的阶段。

需要我们工程设置:

  • dev-app-update.yml: 指向一个本地静态服务器,模拟提供更新
  • 可以进一步抓包看看访问地址是什么

electron-updater 会提示 Skip checkForUpdates because application is not packed and dev update config is not forced:

  • 这时候,需要我们在 app.getAppPath() 同级的目录下 dev-app-update.yml, 并且配置 autoUpdater.forceDevUpdateConfig 才会去读取 dev-app-update.yml 的配置

技术总结