加载中...

Tauri 应用自动更新 | Updater

Tauri 应用自动更新 | Updater

正常的应用程序更新需要手动下载并安装,而借助 Tauri 内置的 Updater 程序 ,我们可以实现应用程序的自动更新推送

下面将介绍如何在 tauri 项目中实现自动更新推送的过程(仅windows环境)。为了避免给后端增加工作量,我选择静态json文件来配置更新信息,json与安装包同时保存在 minioOSS 中

实现步骤

1. 生成签名

使用签名可以确保文件的完整性和来源可信性,在项目根目录执行命令 npm run tauri signer generate -- -w ./app.key

后生成 app.key 和 app.key.pub(公钥) 文件

2. 配置 Updater

文档: tauri.app/zh-cn/v1/ap…

确保 Tauri 项目配置文件(tauri.conf.json)已经正确配置 Updater:

json5
代码解读
复制代码
{ "updater": { "active": true, // 更新程序是否激活 "dialog": false, // 显示内置对话框,太丑了我不用 "pubkey": "xxx", // app.key.pub签名公钥 "endpoints": [ "https://xxx/updater.json" // 更新元数据的静态json文件地址 ] } }
  • endpoints:数组,通过地址列表来确定服务器端是否有可用更新,字符串 {{target}} 和 {{current_version}} 会在 URL 中自动替换。如果指定了多个地址,服务器在预期时间内未响应,更新程序将依次尝试。 endpoints 支持两种格式:

    • 动态接口 - 服务器根据客户端的更新请求确定是否需要更新。 如果需要更新,服务器应以状态代码 200 OK 进行响应,并在正文中包含更新 JSON。 如果不需要更新,服务器必须响应状态代码 204 No Content。
    • 静态文件 - 备用更新技术使用纯 JSON 文件,将更新元数据存储在 gist,github-pages 或其他静态文件存储中。(我选择的)

配置完成后执行构建客户端的命令得到安装包,别忘了开启 updater 后的构建需要环境变量 TAURI_PRIVATE_KEY、TAURI_KEY_PASSWORD

3. 编辑静态json文件(保存更新元数据)

文档: tauri.app/zh-cn/v1/gu…

由于关闭了内置更新对话框,需要在程序内手动检查更新,并执行后续的交互逻辑:

json5
代码解读
复制代码
// updater.json { "version": "v1.0.0", // 版本号,版本格式:主版本号.次版本号.修订号 "notes": "new Version", // 更新说明 "pub_date": "2024-01-26T01:57:18.253Z", // RFC 3339 "platforms": { "windows-x86_64": { "signature": "xxx", // 私钥,app.key内容 "url": "https://xxx/xxx.nsis.zip" // 安装包地址 } } }

4. 程序内手动检查更新

自定义弹窗:tauri.app/zh-cn/v1/gu…

typescript
代码解读
复制代码
checkUpdate().then((res) => { const {shouldUpdate, manifest} = res; if (shouldUpdate) { Modal.confirm({ title: `发现新版本:${manifest?.version}`, content: `是否升级?`, okText: ''升级'', cancelText: ''取消'', onOk: async () => { try { notification.info({ message: ''正在下载更新...'', duration: 3000, }); await installUpdate(); await relaunch(); } catch (e) { notification.error({ message: ''下载更新失败'', description: e?.toString() || '''', }); } }, }); } });

5. 手动上传文件到 minioOSS

将 updater.json 和 安装包.zip 文件上传到 minioOSS 中,然后将地址替换。在每次发版时手动修改 updater.json 中的信息,再重新构建并上传安装包。

一切顺利时客户端将收到更新

6. 懒人模式(脚本)

  • 在 node 环境内执行构建命令,并继承环境变量
typescript
代码解读
复制代码
execSync(''npm run tauri build'', { stdio: ''inherit'', env: { ...process.env, TAURI_PRIVATE_KEY, TAURI_KEY_PASSWORD, }, });
  • 登录 minio 并获取cookie

    typescript
    代码解读
    复制代码
    async function login() { try { // 拿到header内的cookie const res = await axios.post(''https://xxx/xxx/login'', { accessKey: ''xxx'', secretKey: ''xxx'', }); return res?.headers?.[''set-cookie'']?.toString(); } catch (err) { console.log(''登录minio失败''); console.log(err); } }
  • 上传文件到 minio

    typescript
    代码解读
    复制代码
    async function uploadFile(data, cookie) { try { await request.post( `https://xxx/buckets/xxx/objects/upload`, data, { headers: { Cookie: cookie, ''Content-Type'': ''multipart/form-data'', }, }, ); } catch (err) { console.log(''上传文件失败''); console.log(err); } }
  • 读取本地安装包并上传

    typescript
    代码解读
    复制代码
    const FormData = require(''form-data''); const fs = require(''fs''); // 读取本地的 updater.json 文件 const buffer_updater = fs.readFileSync(''./xxx/updater.json'') // 模拟 formData 格式上传 const formData_updater = new FormData() formData_updater.append(buffer_updater.length.toString(), buffer_updater) await uploadFile(formData_updater, cookie) // 上传安装包同理