跳转到内容
Tauri

更新

自动使用更新服务器或静态 JSON 更新你的 Tauri 应用程序。

Supported Platforms

This plugin requires a Rust version of at least 1.77.2

Platform Level Notes
windows
linux
macos
android
ios

Setup

从安装 Tauri 更新插件开始。

使用项目的包管理器添加依赖项。

npm run tauri add updater

签名更新包

Tauri 的更新程序需要签名来验证更新来自可信来源。这不能被禁用。

要对更新进行签名,你需要两个密钥:

  1. 公钥将在 tauri.conf.json 中设置,以便在安装前验证升级包。只要您的私钥是安全的,此公钥就可以安全地上传和共享。
  2. 私钥,用于为安装程序文件签名。你不应该与任何人共享这把钥匙。此外,如果你丢失了这个密钥,你将无法向已经安装应用程序的用户发布新的更新。把这个密钥放在安全的地方很重要!

为了生成密钥,Tauri CLI 提供了 signer generate 命令。你可以运行以下命令在主文件夹中创建密钥。

npm run tauri signer generate -- -w ~/.tauri/myapp.key

构建

在构建您的更新包时,您需要在环境变量中配置上述生成的私钥。.env 文件不起作用!

export TAURI_SIGNING_PRIVATE_KEY="Path or content of your private key"
# optionally also add a password
export TAURI_SIGNING_PRIVATE_KEY_PASSWORD=""

之后,您可以像往常一样运行 Tauri build,Tauri 将生成更新包及其签名。 生成的文件依赖于下面配置的 createUpdaterArtifacts 配置值。

{
"bundle": {
"createUpdaterArtifacts": true
}
}

在 Linux 上,Tauri 将在 target/release/bundle/appimage/ 文件夹中创建 AppImage。

  • myapp.AppImage - 标准的应用程序包。它将被更新者重新使用。
  • myapp.AppImage.sig - 更新包的签名。

在 macOS 系统上,Tauri 会从 target/release/bundle/macos/ 文件夹内的应用程序包创建一个 .tar.gz 归档文件。

  • myapp.app - 标准的应用程序包。
  • myapp.app.tar.gz - 更新包。
  • myapp.app.tar.gz.sig - 更新包的签名。

在 Windows 系统上,Tauri 会在 target/release/bundle/msi/ and target/release/bundle/nsis 文件夹内创建常规的 MSI 和 NSIS 安装程序。

  • myapp-setup.exe - 标准的应用程序包。它将被更新者重新使用。
  • myapp-setup.exe.sig - 更新包的签名。
  • myapp.msi - 标准的应用程序包。它将被更新者重新使用。
  • myapp.msi.sig - 更新包的签名。

Tauri 配置

以这种格式设置 tauri.conf.json,以使更新程序开始工作。

KeysDescription
createUpdaterArtifacts将其设置为 true 告诉 Tauri 的应用打包器创建更新包。如果你要从较旧的 Tauri 版本迁移应用程序,请将其设置为 "v1Compatible"此设置将在 v3 中删除,所以一旦所有用户迁移到 v2,请确保将其更改为 true
pubkey这必须是上面步骤中从 Tauri CLI 生成的公钥。它不能是文件路径!
endpoints这必须是一个字符串形式的 url 数组。TLS 在生产模式下强制执行。只有返回非 2xx 状态码时,Tauri 才会继续访问下一个 url!
dangerousInsecureTransportProtocol将其设置为 true 允许更新器接受非 https 端点。请谨慎使用此配置!

每个更新的 URL 可以包含以下动态变量,允许您在服务器端确定更新是否可用。

  • {{current_version}}:请求更新的应用程序版本。
  • {{target}}:操作系统名称 (linuxwindowsdarwin 之一)。
  • {{arch}}:机器的架构 (x86_64i686aarch64armv7 之一)。
tauri.conf.json
{
"bundle": {
"createUpdaterArtifacts": true
},
"plugins": {
"updater": {
"pubkey": "CONTENT FROM PUBLICKEY.PEM",
"endpoints": [
"https://releases.myapp.com/{{target}}/{{arch}}/{{current_version}}",
// or a static github json file
"https://github.com/user/repo/releases/latest/download/latest.json"
]
}
}
}

installMode on Windows

在 Windows 平台上,有一个额外的可选的 "installMode" 配置来更改更新包的安装方式。

tauri.conf.json
{
"plugins": {
"updater": {
"windows": {
"installMode": "passive"
}
}
}
}
  • "passive":会有一个带有进度条的小窗口。该更新将在不需要任何用户交互的情况下安装。一般推荐使用默认模式。
  • "basicUi":将显示一个基本的用户界面,它需要用户交互来完成安装。
  • "quiet":没有进度反馈给用户。在这种模式下,安装程序不能自行请求管理员权限,所以它只适用于用户范围内的安装,或者当您的应用程序本身已经以管理员权限运行时。一般不推荐。

服务器的支持

更新插件可以以两种方式使用。要么使用动态更新服务器,要么使用静态 JSON 文件(用于 S3 或 GitHub gist 等服务)。

静态 JSON 文件

使用静态文件时,只需要返回一个包含所需信息的 JSON。

KeysDescription
version必须是一个有效的 SemVer,带或不带 v,这意味着 1.0.0v1.0.0 都是有效的。
notes更新说明。
pub_date如果存在日期,则必须按照 RFC 3339 规范格式化。
platforms每个平台的字段名都是 OS-ARCH 格式,其中 OSlinuxdarwinwindows 中的一个,而 ARCHx86_64aarch64i686armv7 中的一个。
signature生成的 .sig 文件的内容,可能会随着每次构建而改变。路径或 URL 将不起作用!

当使用自定义目标时,所提供的目标字符串会与 platforms 键进行匹配,而非默认的 OS-ARCH 值。

"version""platforms.[target].url""platforms.[target].signature" 是必需的;其它字段是可选的。

{
"version": "",
"notes": "",
"pub_date": "",
"platforms": {
"linux-x86_64": {
"signature": "",
"url": ""
},
"windows-x86_64": {
"signature": "",
"url": ""
},
"darwin-x86_64": {
"signature": "",
"url": ""
}
}
}

注意,Tauri 将在检查 version 字段之前验证整个文件,因此请确保所有现有平台配置都是有效和完整的。

动态更新服务器

在使用动态更新服务器时,Tauri 会遵循服务器的指令。若要禁用内部版本检查,您可以覆盖 Tauri 的版本比较,这样就会安装服务器发送的版本(如果您需要回滚应用程序,这很有用)。

您的服务器可以使用上述 endpoint URL 中定义的变量来确定是否需要更新。如果您需要更多数据,可以根据自己的喜好在 Rust 中添加额外的请求头

如果没有可用的更新,您的服务器应响应状态码为 204 无内容

如果需要更新,您的服务器应使用状态码 200 OK 进行响应,并以这种格式提供 JSON 响应。

KeysDescription
version必须是一个有效的 SemVer,带或不带 v,这意味着 1.0.0v1.0.0 都是有效的。
notes更新说明。
pub_date如果存在日期,则必须按照 RFC 3339 规范格式化。
url这必须是的有效更新包 URL。
signature生成的 .sig 文件的内容,可能会随着每次构建而改变。路径或 URL 将不起作用!

"url""version" and "signature" 是必须的;其它字段是可选的。

{
"version": "",
"pub_date": "",
"url": "",
"signature": "",
"notes": ""
}

检查更新

用于检查和安装更新的默认 API 利用配置的端点,可以由 JavaScript 和 Rust 代码访问。

import { check } from '@tauri-apps/plugin-updater';
import { relaunch } from '@tauri-apps/plugin-process';
const update = await check();
if (update) {
console.log(
`found update ${update.version} from ${update.date} with notes ${update.body}`
);
let downloaded = 0;
let contentLength = 0;
// alternatively we could also call update.download() and update.install() separately
await update.downloadAndInstall((event) => {
switch (event.event) {
case 'Started':
contentLength = event.data.contentLength;
console.log(`started downloading ${event.data.contentLength} bytes`);
break;
case 'Progress':
downloaded += event.data.chunkLength;
console.log(`downloaded ${downloaded} from ${contentLength}`);
break;
case 'Finished':
console.log('download finished');
break;
}
});
console.log('update installed');
await relaunch();
}

更多有关信息,请参阅 JavaScript API 文档

请注意,安装更新后不需要立即重启应用程序,你可以选择如何处理更新,要么等待用户手动重启应用程序,要么提示他选择何时这样做。

当检查和下载更新时,可以定义自定义的请求超时、代理和请求头。

import { check } from '@tauri-apps/plugin-updater';
const update = await check({
proxy: '<proxy url>',
timeout: 30000 /* milliseconds */,
headers: {
Authorization: 'Bearer <token>',
},
});

运行时配置

更新 api 还允许在运行时配置更新程序,以获得更大的灵活性。 出于安全原因,一些 api 仅对 Rust 可用。

Endpoints

设置运行时检查更新的 url 可以允许更多的动态更新,例如单独的发布通道:

use tauri_plugin_updater::UpdaterExt;
let channel = if beta { "beta" } else { "stable" };
let update_url = format!("https://{channel}.myserver.com/{{{{target}}}}-{{{{arch}}}}/{{{{current_version}}}}");
let update = app
.updater_builder()
.endpoints(vec![update_url])?
.build()?
.check()
.await?;

公钥

在运行时设置公钥对于实现密钥轮换逻辑可能很有用。 它可以由插件构建器或更新器构建器设置:

tauri_plugin_updater::Builder::new().pubkey("<your public key>").build()
use tauri_plugin_updater::UpdaterExt;
let update = app
.updater_builder()
.pubkey("<your public key>")
.build()?
.check()
.await?;

自定义目标

默认情况下,更新程序允许您使用 {{target}} and {{arch}} 变量来确定必须交付哪个更新资产。 如果您需要有关更新的更多信息(例如,在分发通用 macOS 二进制选项或有更多构建风格时),您可以设置自定义目标。

import { check } from '@tauri-apps/plugin-updater';
const update = await check({
target: 'macos-universal',
});

允许降级

默认情况下,Tauri 会检查更新版本是否大于当前应用程序版本,以验证是否应该更新。 为了允许降级,你必须使用更新构建器的 version_comparator API。

use tauri_plugin_updater::UpdaterExt;
let update = app
.updater_builder()
.version_comparator(|current, update| {
// default comparison: `update.version > current`
update.version != current
})
.build()?
.check()
.await?;

窗口退出前的钩子函数

由于 Windows 安装程序的限制,Tauri 会在 Windows 上安装更新之前自动退出您的应用程序。 要在此之前执行操作,请使用 on_before_exit 函数。

use tauri_plugin_updater::UpdaterExt;
let update = app
.updater_builder()
.on_before_exit(|| {
println!("app is about to exit on Windows!");
})
.build()?
.check()
.await?;

权限

默认情况下,所有潜在危险的插件命令和范围都被阻止且无法访问。您必须在您的 capabilities 配置中修改权限以启用这些。

有关更多信息,请参阅功能概述,以及使用插件权限的分步指南

src-tauri/capabilities/default.json
{
"permissions": [
...,
"updater:default",
]
}

Default Permission

This permission set configures which kind of updater functions are exposed to the frontend.

Granted Permissions

The full workflow from checking for updates to installing them is enabled.

  • allow-check
  • allow-download
  • allow-install
  • allow-download-and-install

Permission Table

Identifier Description

updater:allow-check

Enables the check command without any pre-configured scope.

updater:deny-check

Denies the check command without any pre-configured scope.

updater:allow-download

Enables the download command without any pre-configured scope.

updater:deny-download

Denies the download command without any pre-configured scope.

updater:allow-download-and-install

Enables the download_and_install command without any pre-configured scope.

updater:deny-download-and-install

Denies the download_and_install command without any pre-configured scope.

updater:allow-install

Enables the install command without any pre-configured scope.

updater:deny-install

Denies the install command without any pre-configured scope.


© 2025 Tauri Contributors. CC-BY / MIT