更新器
使用更新服务器或静态 JSON 自动更新 Tauri 应用程序。
此插件需要 Rust 版本至少为 **1.77.2**
平台 | 级别 | 备注 |
---|---|---|
windows | ||
linux | ||
macos | ||
android | | |
ios | |
安装 Tauri 更新器插件即可开始使用。
使用你的项目包管理器添加依赖项
npm run tauri add updater
yarn run tauri add updater
pnpm tauri add updater
deno task tauri add updater
bun tauri add updater
cargo tauri add updater
-
在
src-tauri
文件夹中运行以下命令,将插件添加到项目的Cargo.toml
依赖项中cargo add tauri-plugin-updater --target 'cfg(any(target_os = "macos", windows, target_os = "linux"))' -
修改
lib.rs
以初始化插件lib.rs #[cfg_attr(mobile, tauri::mobile_entry_point)]pub fn run() {tauri::Builder::default().setup(|app| {#[cfg(desktop)]app.handle().plugin(tauri_plugin_updater::Builder::new().build());Ok(())}).run(tauri::generate_context!()).expect("error while running tauri application");} -
您可以使用首选的 JavaScript 包管理器安装 JavaScript 客户端绑定
npm install @tauri-apps/plugin-updateryarn add @tauri-apps/plugin-updaterpnpm add @tauri-apps/plugin-updaterdeno add npm:@tauri-apps/plugin-updaterbun add @tauri-apps/plugin-updater
Tauri 的更新器需要签名来验证更新是否来自受信任的来源。此功能无法禁用。
要签名您的更新,您需要两把密钥
- 公钥,将在
tauri.conf.json
中设置,用于在安装前验证构件。只要您的私钥是安全的,此公钥就可以安全上传和共享。 - 私钥,用于签名您的安装程序文件。您绝不应该与任何人共享此密钥。此外,如果您丢失此密钥,您将无法向已安装应用程序的用户发布新更新。将此密钥存储在安全的地方非常重要!
要生成密钥,Tauri CLI 提供了 signer generate
命令。您可以运行此命令在主文件夹中创建密钥
npm run tauri signer generate -- -w ~/.tauri/myapp.key
yarn tauri signer generate -w ~/.tauri/myapp.key
pnpm tauri signer generate -w ~/.tauri/myapp.key
deno task tauri signer generate -w ~/.tauri/myapp.key
bunx tauri signer generate -w ~/.tauri/myapp.key
cargo tauri signer generate -w ~/.tauri/myapp.key
构建更新构件时,您需要将上面生成的私钥放在环境变量中。.env
文件不起作用!
export TAURI_SIGNING_PRIVATE_KEY="Path or content of your private key"# optionally also add a passwordexport TAURI_SIGNING_PRIVATE_KEY_PASSWORD=""
在 PowerShell
中运行此命令
$env:TAURI_SIGNING_PRIVATE_KEY="Path or content of your private key"<# optionally also add a password #>$env:TAURI_SIGNING_PRIVATE_KEY_PASSWORD=""
之后,您可以像往常一样运行 Tauri 构建,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/ 和 target/release/bundle/nsis 文件夹中创建正常的 MSI 和 NSIS 安装程序
myapp-setup.exe
- 标准应用程序包。它将被更新器重复使用。myapp-setup.exe.sig
- 更新包的签名。myapp.msi
- 标准应用程序包。它将被更新器重复使用。myapp.msi.sig
- 更新包的签名。
{ "bundle": { "createUpdaterArtifacts": "v1Compatible" }}
在 Linux 上,Tauri 会在 target/release/bundle/appimage/
文件夹中从 AppImage 创建一个 .tar.gz 归档文件
myapp.AppImage
- 标准应用程序包。myapp.AppImage.tar.gz
- 更新包。myapp.AppImage.tar.gz.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/ 和 target/release/bundle/nsis 文件夹中从 MSI 和 NSIS 安装程序创建 .zip 归档文件
myapp-setup.exe
- 标准应用程序包。myapp-setup.nsis.zip
- 更新包。myapp-setup.nsis.zip.sig
- 更新包的签名。myapp.msi
- 标准应用程序包。myapp.msi.zip
- 更新包。myapp.msi.zip.sig
- 更新包的签名。
将 tauri.conf.json
配置成这种格式,更新器才能开始工作。
键 | 描述 |
---|---|
createUpdaterArtifacts | 将其设置为 true 会告诉 Tauri 的应用程序打包器创建更新工件。如果您正在从旧的 Tauri 版本迁移应用程序,请将其设置为 "v1Compatible" 。此设置将在 v3 中删除,因此请确保在所有用户都迁移到 v2 后将其更改为 true 。 |
pubkey | 这必须是上述步骤中从 Tauri CLI 生成的公钥。它不能是文件路径! |
endpoints | 这必须是 URL 字符串的端点数组。在生产模式下强制执行 TLS。Tauri 只有在返回非 2XX 状态码时才会继续访问下一个 URL! |
dangerousInsecureTransportProtocol | 将其设置为 true 允许更新程序接受非 HTTPS 端点。请谨慎使用此配置! |
每个更新器 URL 可以包含以下动态变量,允许您在服务器端确定是否有可用更新。
{{current_version}}
:请求更新的应用程序版本。{{target}}
:操作系统名称(linux
、windows
或darwin
之一)。{{arch}}
:机器的架构(x86_64
、i686
、aarch64
或armv7
之一)。
{ "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" ] } }}
在 Windows 上,有一个额外的可选 "installMode"
配置,用于更改更新的安装方式。
{ "plugins": { "updater": { "windows": { "installMode": "passive" } } }}
"passive"
:将出现一个带有进度条的小窗口。更新将在不需要任何用户交互的情况下安装。通常推荐并作为默认模式。"basicUi"
:将显示一个基本的用户界面,需要用户交互才能完成安装。"quiet"
:不会向用户提供进度反馈。在这种模式下,安装程序无法自行请求管理员权限,因此它只在用户范围的安装中或您的应用程序本身已以管理员权限运行时才有效。通常不推荐。
更新器插件有两种使用方式。可以使用动态更新服务器,也可以使用静态 JSON 文件(用于 S3 或 GitHub gist 等服务)。
使用静态时,您只需返回包含所需信息的 JSON。
键 | 描述 |
---|---|
版本 | 必须是有效的 SemVer,可以带前导 v ,也可以不带,这意味着 1.0.0 和 v1.0.0 都有效。 |
注意事项 | 有关更新的备注。 |
pub_date | 如果存在,日期必须按照 RFC 3339 格式化。 |
平台 | 每个平台键都采用 OS-ARCH 格式,其中 OS 是 linux 、darwin 或 windows 之一,ARCH 是 x86_64 、aarch64 、i686 或 armv7 之一。 |
签名 | 生成的 .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 会在检查版本字段之前验证整个文件,因此请确保所有现有平台配置都有效且完整。
当使用动态更新服务器时,Tauri 会遵循服务器的指令。要禁用内部版本检查,您可以覆盖插件的版本比较,这将安装服务器发送的版本(如果您需要回滚应用程序,这很有用)。
您的服务器可以使用上面 endpoint
URL 中定义的变量来确定是否需要更新。如果您需要更多数据,可以在 Rust 中包含额外的请求头。
如果没有可用更新,您的服务器应返回 204 No Content
状态码。
如果需要更新,您的服务器应返回 200 OK
状态码和以下格式的 JSON 响应
键 | 描述 |
---|---|
版本 | 这必须是有效的 SemVer,无论是否带前导 v ,即 1.0.0 和 v1.0.0 都有效。 |
注意事项 | 有关更新的备注。 |
pub_date | 如果存在,日期必须按照 RFC 3339 格式化。 |
url | 这必须是更新包的有效 URL。 |
签名 | 生成的 .sig 文件的内容,可能会随每次构建而变化。路径或 URL 无效! |
必填键是 "url"
、"version"
和 "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 文档。
use tauri_plugin_updater::UpdaterExt;
pub fn run() { tauri::Builder::default() .setup(|app| { let handle = app.handle().clone(); tauri::async_runtime::spawn(async move { update(handle).await.unwrap(); }); Ok(()) }) .run(tauri::generate_context!()) .unwrap();}
async fn update(app: tauri::AppHandle) -> tauri_plugin_updater::Result<()> { if let Some(update) = app.updater()?.check().await? { let mut downloaded = 0;
// alternatively we could also call update.download() and update.install() separately update .download_and_install( |chunk_length, content_length| { downloaded += chunk_length; println!("downloaded {downloaded} from {content_length:?}"); }, || { println!("download finished"); }, ) .await?;
println!("update installed"); app.restart(); }
Ok(())}
有关更多信息,请参阅 Rust API 文档。
请注意,在安装更新后立即重新启动应用程序不是必需的,您可以选择如何处理更新,即等待用户手动重新启动应用程序,或提示用户选择何时重新启动。
检查和下载更新时,可以定义自定义请求超时、代理和请求头。
import { check } from '@tauri-apps/plugin-updater';
const update = await check({ proxy: '<proxy url>', timeout: 30000 /* milliseconds */, headers: { Authorization: 'Bearer <token>', },});
use tauri_plugin_updater::UpdaterExt;let update = app .updater_builder() .timeout(std::time::Duration::from_secs(30)) .proxy("<proxy-url>".parse().expect("invalid URL")) .header("Authorization", "Bearer <token>") .build()? .check() .await?;
更新器 API 还允许在运行时配置更新器,以获得更大的灵活性。出于安全考虑,某些 API 仅适用于 Rust。
在运行时设置用于检查更新的 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}}
和 {{arch}}
变量来确定要交付的更新资产。如果您需要更多关于更新的信息(例如,在分发通用 macOS 二进制选项或有更多构建版本时),您可以设置自定义目标。
import { check } from '@tauri-apps/plugin-updater';
const update = await check({ target: 'macos-universal',});
自定义目标可以通过插件构建器或更新器构建器设置
tauri_plugin_updater::Builder::new().target("macos-universal").build()
use tauri_plugin_updater::UpdaterExt;let update = app .updater_builder() .target("macos-universal") .build()? .check() .await?;
默认情况下,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
配置中的权限才能启用这些功能。
有关更多信息,请参阅功能概述,并参阅分步指南以使用插件权限。
{ "permissions": [ ..., "updater:default", ]}
默认权限
此权限集配置了哪些更新器功能暴露给前端。
已授予权限
从检查更新到安装更新的完整工作流已启用。
此默认权限集包括以下内容
允许检查
允许下载
允许安装
允许下载和安装
权限表
标识符 | 描述 |
---|---|
|
启用检查命令,无需任何预配置的作用域。 |
|
拒绝检查命令,无需任何预配置的作用域。 |
|
启用下载命令,无需任何预配置的作用域。 |
|
拒绝下载命令,无需任何预配置的作用域。 |
|
启用 download_and_install 命令,无需任何预配置的作用域。 |
|
拒绝 download_and_install 命令,无需任何预配置的作用域。 |
|
启用安装命令,无需任何预配置的作用域。 |
|
拒绝安装命令,无需任何预配置的作用域。 |
© 2025 Tauri 贡献者。CC-BY / MIT