人人都会AI编程

7.2 Rust 主进程入口与核心概念

更新时间:2026-07-11

在 Tauri 应用中,Rust 主进程是应用的后台核心,负责管理窗口、处理系统调用、运行后台任务,并与前端通过 IPC 通信。理解它的入口与几个关键概念,是写好 Tauri 应用的基础。


1. 主程序入口:main.rs

Tauri 应用的 Rust 入口通常在 src-tauri/src/main.rs(若使用 Tauri CLI 初始化项目,默认如此)。最基本的骨架如下:

#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

fn main() {
    tauri::Builder::default()
        .run(tauri::generate_context!())
        .expect("启动应用时出错");
}
  • #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]:在 Windows 发布模式下不显示控制台窗口。
  • tauri::Builder::default():创建一个默认的应用构建器。
  • .run(tauri::generate_context!()):加载 tauri.conf.json 配置,启动 WebView 窗口并运行事件循环。调用后主线程会被阻塞,直到应用退出。

这已经是一个可以运行的 Tauri 应用——它会根据 tauri.conf.json 中的 build.devPathbuild.distDir 加载前端页面。


2. 命令(Commands):前端调用的 Rust 函数

前端无法直接访问系统,必须通过“命令”来调用 Rust 函数。定义一个命令非常简单:

#[tauri::command]
fn greet(name: &str) -> String {
    format!("你好,{}!", name)
}

然后在 main 里注册:

fn main() {
    tauri::Builder::default()
        .invoke_handler(tauri::generate_handler![greet])
        .run(tauri::generate_context!())
        .expect("启动应用时出错");
}

前端通过 @tauri-apps/api 调用:

import { invoke } from '@tauri-apps/api/tauri';
const msg = await invoke('greet', { name: 'Tauri' });

核心要点

  • 命令参数和返回值必须实现 serde::Serialize / Deserialize
  • 参数名会与前端传递的 JSON 字段自动匹配。
  • 命令中可以使用 tauri::Window, tauri::State 等特殊类型来访问应用状态或窗口实例。

3. 应用状态(State):跨命令共享数据

Tauri 用 Rust 的“状态管理”模式来共享资源,例如数据库连接、配置对象等。在 Builder 上注册状态:

struct AppConfig {
    app_name: String,
}

fn main() {
    tauri::Builder::default()
        .manage(AppConfig { app_name: "MyApp".into() })
        .invoke_handler(tauri::generate_handler![get_app_name])
        .run(tauri::generate_context!())
        .unwrap();
}

#[tauri::command]
fn get_app_name(config: tauri::State<AppConfig>) -> String {
    config.app_name.clone()
}

State<T> 会自动注入,多个命令可以共享同一个 T 的实例(注意 T 必须 Send + Sync)。对于需要互斥访问的数据,通常内部使用 std::sync::Mutextokio::sync::Mutex


4. 窗口与菜单管理

Tauri 的 Builder 允许你在启动时创建窗口,也可以在运行时动态创建。配置窗口最直接的方式在 tauri.conf.jsonwindows 数组中,但也可以通过 Rust 代码配合 tauri::WindowBuilder

use tauri::Manager;

fn main() {
    tauri::Builder::default()
        .setup(|app| {
            let _window = tauri::WindowBuilder::new(
                app,
                "label",
                tauri::WindowUrl::App("index.html".into()),
            )
            .title("新窗口")
            .inner_size(800.0, 600.0)
            .build()?;
            Ok(())
        })
        .run(tauri::generate_context!())
        .unwrap();
}
  • app.get_window("label") 可获取已存在的窗口。
  • 菜单、系统托盘也通过 Rust 端创建,并可用 on_menu_event 等闭包处理点击。

5. 事件系统:前后端双向通信

除了命令(前端→后端),Tauri 还支持前后端之间的事件推送。

  • 后端向所有窗口广播事件
  use tauri::Manager;
  app.emit_all("backend-event", "some data")?;
  
  • 后端向指定窗口发送事件
  window.emit("custom-event", payload)?;
  
  • 前端监听事件
  import { listen } from '@tauri-apps/api/event';
  const unlisten = await listen('backend-event', (event) => {
      console.log(event.payload);
  });
  
  • 前端向后端发送事件:用 invoke 或使用 emit 通过全局事件通道(通过 App::run() 返回的 EventLoopProxy 等,但更推荐命令模式)。

6. 插件系统

Tauri 2.x 的插件系统允许将功能打包为可复用的 crate。例如,要使用 tauri-plugin-shell 执行系统命令,只需:

  1. Cargo.toml 添加依赖 tauri-plugin-shell
  2. main.rs 中注册:
   fn main() {
       tauri::Builder::default()
           .plugin(tauri_plugin_shell::init())
           .run(tauri::generate_context!())
           .unwrap();
   }
   
  1. 前端通过 JavaScript API 调用,如 import { Command } from '@tauri-apps/plugin-shell';

插件机制让核心保持轻量,按需组合文件系统、剪贴板、通知等功能。


7. 生命周期与退出

Tauri 应用的事件循环会自动运行,直到所有窗口关闭(或调用 app.exit())。你可以通过 Builder 上的 on_window_eventon_exit 闭包处理关闭前的清理逻辑:

tauri::Builder::default()
    .on_window_event(|event| {
        if let tauri::WindowEvent::CloseRequested { api, .. } = event.event() {
            // 可以阻止关闭或做保存操作
        }
    })
    .build(tauri::generate_context!())
    .expect("error while building tauri application")
    .run(|_app_handle, event| {
        match event {
            tauri::RunEvent::ExitRequested { api, .. } => {
                // 处理退出
            }
            _ => {}
        }
    });

一句话总结:Rust 主进程是 Tauri 应用的“大脑”,通过 Builder 将所有核心概念(命令、状态、事件、插件)串联起来,让你用最少的代码把系统能力暴露给前端,同时保持安全与高性能。