Tauri 是一个基于 Rust 和 Web 技术构建跨平台桌面应用的现代框架,其核心优势在于轻量级和高性能。自动更新功能对提升用户体验、确保应用安全至关重要,尤其在频繁迭代的开发场景中。本文将深入分析 Tauri 支持的自动更新机制,结合官方实践与代码示例,提供可落地的实现方案。Tauri 本身不直接内置更新系统,但通过插件化设计,能无缝集成第三方更新库,实现高效的版本管理。
Tauri 支持的自动更新方式
1. 基于 tauri-plugin-updater 的官方推荐方案
Tauri 官方强烈推荐使用 tauri-plugin-updater 插件(基于 electron-updater 的 Rust 实现),它提供开箱即用的 GitHub Releases 集成能力,支持 Windows、macOS 和 Linux 三大平台。
核心特性:
- 自动版本检测:通过
check_update()方法定期扫描新版本。 - 用户交互:提供弹窗提示和进度条,避免强制更新导致的用户流失。
- 多源支持:兼容 GitHub Releases、自定义 API 等更新源。
实现步骤:
- 添加插件依赖到
Cargo.toml:
toml[dependencies] tauri = { version = "2.0", features = ["updater"] } # 可选:添加 HTTP 客户端(如 reqwest) reqwest = "0.11"
- 配置更新服务:在
src/main.rs中初始化插件并设置更新源。例如,使用 GitHub Releases 作为源:
rustuse tauri::AppHandle; use tauri_plugin_updater::Updater; fn main() { let app = tauri::Builder::default() .plugin(tauri_plugin_updater::init()) .build() .expect("failed to build app"); // 通过 GitHub Releases 源配置(示例) let updater = app.updater(); updater.set_release_url("https://api.github.com/repos/your-repo/releases").await; }
- 处理更新事件:在应用生命周期中调用更新逻辑。
rust// 在事件处理器中触发更新检查 app.updater().check_update().await; // 监听更新状态(示例) app.updater().on_update(|status| { match status { tauri_plugin_updater::UpdateStatus::NewVersionAvailable => { // 显示用户提示 println!("New version available: {}", status.version); } tauri_plugin_updater::UpdateStatus::UpdateCompleted => { // 重启应用 app.restart().unwrap(); } } });
2. 自定义更新实现:深度集成与灵活性
对于需要高度定制化场景(如私有仓库或复杂逻辑),可绕过官方插件,直接使用 reqwest 和 serde 实现更新逻辑。
技术方案:
- HTTP 请求:通过
reqwest获取更新信息,解析 JSON 数据。 - 下载与安装:使用
std::fs处理文件下载和替换。
关键代码示例:
rustuse reqwest::blocking::get; use serde_json::Value; use std::fs; fn check_for_update() -> Result<(), Box<dyn std::error::Error>> { let response = get("https://api.example.com/updates/v1").unwrap(); let json: Value = response.json().unwrap(); // 检查新版本号 if let Some(new_version) = json["version"]["tag_name"]["as_str"]["as_str"]["as_str"] { let current_version = env::var("APP_VERSION").unwrap_or("1.0.0"); if new_version > current_version { // 下载更新包(简化示例) let download_url = json["assets"][0]["browser_download_url"]["as_str"]["as_str"]["as_str"]; let mut response = get(&download_url).unwrap(); let mut file = File::create("app-update.exe").unwrap(); // 根据平台调整 std::io::copy(&mut response, &mut file).unwrap(); // 安装逻辑:替换可执行文件并重启 std::process::Command::new("app-update.exe").spawn().unwrap(); } } Ok(()) }