更新器
使用更新服务器或静态 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 Guest 绑定
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 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/ 和 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 配置
设置 tauri.conf.json
为此格式,以便更新器开始工作。
键 | 描述 |
---|---|
createUpdaterArtifacts | 将此项设置为 true 会告知 Tauri 的应用程序打包器创建更新器工件。如果你正在从旧版本的 Tauri 迁移你的应用程序,请将其设置为 "v1Compatible" 。此设置将在 v3 中移除,因此请确保在所有用户都迁移到 v2 后将其更改为 true 。 |
pubkey | 这必须是上面步骤中从 Tauri CLI 生成的公钥。它不能是文件路径! |
endpoints | 这必须是字符串形式的端点 URL 数组。TLS 在生产模式下强制执行。如果返回非 2XX 状态代码,Tauri 将仅继续下一个 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
在 Windows 上,还有一个可选的 "installMode"
配置来更改更新的安装方式。
{ "plugins": { "updater": { "windows": { "installMode": "passive" } } }}
"passive"
:将有一个带有进度条的小窗口。更新将无需任何用户交互即可安装。通常建议使用,也是默认模式。"basicUi"
:将显示一个基本用户界面,需要用户交互才能完成安装。"quiet"
:不会向用户提供进度反馈。在这种模式下,安装程序本身无法请求管理员权限,因此它仅在用户范围内的安装或当你的应用程序本身已经以管理员权限运行时才有效。通常不建议使用。
服务器支持
更新器插件可以通过两种方式使用。可以使用动态更新服务器或静态 JSON 文件(用于 S3 或 GitHub gists 等服务)。
静态 JSON 文件
当使用静态时,你只需要返回一个包含所需信息的 JSON。
键 | 描述 |
---|---|
version | 必须是有效的 SemVer,带或不带前导 v ,这意味着 1.0.0 和 v1.0.0 都是有效的。 |
notes | 关于更新的说明。 |
pub_date | 如果存在,日期必须按照 RFC 3339 格式化。 |
platforms | 每个平台键都是 OS-ARCH 格式,其中 OS 是 linux 、darwin 或 windows 之一,ARCH 是 x86_64 、aarch64 、i686 或 armv7 之一。 |
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 将在检查版本字段之前验证整个文件,因此请确保所有现有的平台配置都是有效且完整的。
动态更新服务器
当使用动态更新服务器时,Tauri 将遵循服务器的指令。要禁用内部版本检查,你可以覆盖插件的版本比较,这将安装服务器发送的版本(如果你需要回滚你的应用程序,这将非常有用)。
你的服务器可以使用上面 endpoint
URL 中定义的变量来确定是否需要更新。如果你需要更多数据,你可以在 Rust 中包含额外的 请求标头,以满足你的喜好。
如果没有可用的更新,你的服务器应以 204 No Content
状态代码响应。
如果需要更新,你的服务器应以 200 OK
状态代码和一个 JSON 响应进行响应,格式如下
键 | 描述 |
---|---|
version | 这必须是有效的 SemVer,带或不带前导 v ,这意味着 1.0.0 和 v1.0.0 都是有效的。 |
notes | 关于更新的说明。 |
pub_date | 如果存在,日期必须按照 RFC 3339 格式化。 |
url | 这必须是更新包的有效 URL。 |
signature | 生成的 .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 退出前钩子
由于 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", ]}
默认权限
此权限集配置了哪些类型的更新器功能暴露给前端。
已授予的权限
从检查更新到安装更新的完整工作流程已启用。
此默认权限集包括以下内容
allow-check
allow-download
allow-install
allow-download-and-install
权限表
标识符 | 描述 |
---|---|
|
启用 check 命令,没有任何预配置的作用域。 |
|
拒绝 check 命令,没有任何预配置的作用域。 |
|
启用 download 命令,没有任何预配置的作用域。 |
|
拒绝 download 命令,没有任何预配置的作用域。 |
|
启用 download_and_install 命令,没有任何预配置的作用域。 |
|
拒绝 download_and_install 命令,没有任何预配置的作用域。 |
|
启用 install 命令,没有任何预配置的作用域。 |
|
拒绝 install 命令,没有任何预配置的作用域。 |
© 2025 Tauri Contributors. CC-BY / MIT