Rust跨平台CLI工具开发插件tauri-plugin-cli的使用,Tauri插件助力高效构建命令行界面应用

Rust跨平台CLI工具开发插件tauri-plugin-cli的使用,Tauri插件助力高效构建命令行界面应用

plugin-cli

该插件用于解析命令行接口(CLI)中的参数。

平台支持情况

平台 支持情况
Linux
Windows
macOS
Android x
iOS x

安装要求

此插件要求Rust版本至少为1.77.2

安装方法

推荐以下三种安装方法:

  1. 使用crates.io和npm(最简单,但需要信任发布流程)
  2. 直接从Github使用git标签/修订哈希获取源码(最安全)
  3. 在Tauri项目中通过git子模块安装此仓库,然后使用文件协议导入源码(最安全但使用不便)

Rust插件安装

Cargo.toml中添加以下内容来安装核心插件:

src-tauri/Cargo.toml

# 如果不针对移动设备,可以在`[dependencies]`部分添加依赖
[target."cfg(not(any(target_os = \"android\", target_os = \"ios\")))".dependencies]
tauri-plugin-cli = "2.0.0"
# 或者使用Git:
tauri-plugin-cli = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }

JavaScript绑定安装

可以使用你喜欢的JavaScript包管理器安装JavaScript Guest绑定:

pnpm add @tauri-apps/plugin-cli
# 或
npm add @tauri-apps/plugin-cli
# 或
yarn add @tauri-apps/plugin-cli

# 或者使用Git:
pnpm add https://github.com/tauri-apps/tauri-plugin-cli#v2
# 或
npm add https://github.com/tauri-apps/tauri-plugin-cli#v2
# 或
yarn add https://github.com/tauri-apps/tauri-plugin-cli#v2

基本使用方法

首先需要向Tauri注册核心插件:

src-tauri/src/lib.rs

fn main() {
    tauri::Builder::default()
        .setup(|app| {
            #[cfg(desktop)]
            app.handle().plugin(tauri_plugin_cli::init())?;
            Ok(())
        })
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

之后,可以通过JavaScript处理CLI参数:

import { getMatches } from '@tauri-apps/plugin-cli'

const matches = await getMatches()
if (matches.subcommand?.name === 'run') {
  // 处理`./your-app run $ARGS`命令
  const args = matches.subcommand?.matches.args
  if ('debug' in args) {
    // 处理`./your-app run --debug`命令
  }
} else {
  const args = matches.args
  // 处理`./your-app $ARGS`命令
}

完整示例

以下是一个完整的Tauri CLI应用示例:

项目结构

tauri-cli-demo/
├── src-tauri/
│   ├── Cargo.toml
│   └── src/
│       └── main.rs
└── src/
    └── main.js

依赖配置

src-tauri/Cargo.toml

[package]
name = "tauri-cli-demo"
version = "0.1.0"
edition = "2021"

[dependencies]
tauri = { version = "1.0", features = ["api-all"] }
tauri-plugin-cli = "2.0.0"

Rust主程序

src-tauri/src/main.rs

use tauri::Manager;

// 定义greet命令
#[tauri::command]
fn greet(name: &str) -> String {
    format!("Hello, {}!", name)
}

fn main() {
    tauri::Builder::default()
        // 注册greet命令处理器
        .invoke_handler(tauri::generate_handler![greet])
        .setup(|app| {
            // 初始化CLI插件(仅限桌面平台)
            #[cfg(desktop)]
            app.handle().plugin(tauri_plugin_cli::init())?;
            Ok(())
        })
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

JavaScript前端处理

src/main.js

import { getMatches } from '@tauri-apps/plugin-cli'

async function handleCliArgs() {
  // 获取命令行参数
  const matches = await getMatches()
  
  // 处理greet子命令
  if (matches.subcommand?.name === 'greet') {
    const name = matches.subcommand?.matches.args.name
    if (name) {
      console.log(`Hello, ${name}!`)
    } else {
      console.log('Please provide a name with --name argument')
    }
  } else {
    // 显示可用命令
    console.log('Available commands: greet')
  }
}

// 执行CLI处理
handleCliArgs()

使用说明

  1. 构建并运行应用后,可以通过以下方式使用:

    • ./tauri-cli-demo greet --name John 将输出"Hello, John!"
    • ./tauri-cli-demo greet 将提示需要提供name参数
    • 直接运行./tauri-cli-demo 将显示可用命令列表
  2. 该示例展示了如何:

    • 初始化tauri-plugin-cli插件
    • 在Rust端定义可调用的命令
    • 在JavaScript端解析和处理命令行参数
    • 实现子命令和参数解析功能

1 回复

Rust跨平台CLI工具开发插件tauri-plugin-cli的使用

完整示例demo

下面是一个完整的Tauri CLI应用示例,结合了图形界面和命令行功能:

1. 项目结构

my-tauri-app/
├── src-tauri/
│   ├── Cargo.toml
│   ├── src/
│   │   ├── main.rs
│   │   └── commands.rs
├── src/
│   └── main.js

2. Cargo.toml 配置

[package]
name = "my-tauri-app"
version = "0.1.0"
description = "A Tauri app with CLI support"
authors = ["Your Name <your@email.com>"]

[dependencies]
tauri = { version = "1.2", features = ["api-all"] }
tauri-plugin-cli = "0.1"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
clap = { version = "3.2", features = ["derive"] }

3. Rust后端代码 (src-tauri/src/main.rs)

use tauri::{Manager, Window};
use serde::{Serialize, Deserialize};
use clap::{Parser, Subcommand};

// 定义命令行参数结构
#[derive(Parser, Serialize, Deserialize)]
#[clap(author, version, about, long_about = None)]
struct Cli {
    /// 开启调试模式
    #[clap(short, long)]
    debug: bool,

    /// 输入文件路径
    #[clap(short, long, value_parser)]
    input: Option<String>,

    #[clap(subcommand)]
    command: Option<Commands>,
}

// 定义子命令
#[derive(Subcommand, Serialize, Deserialize)]
enum Commands {
    /// 处理数据
    Process {
        /// 输出文件路径
        #[clap(short, long)]
        output: Option<String>,
    },
    /// 生成报告
    Report {
        /// 报告格式
        #[clap(short, long, value_parser)]
        format: Option<String>,
    },
}

// 主函数
fn main() {
    tauri::Builder::default()
        .plugin(tauri_plugin_cli::init())
        .invoke_handler(tauri::generate_handler![
            handle_cli, 
            process_file,
            interactive_cli
        ])
        .setup(|app| {
            // 检查命令行参数
            match app.cli() {
                Ok(matches) => {
                    if matches.args.contains_key("help") {
                        println!("显示帮助信息...");
                        std::process::exit(0);
                    }
                    
                    if let Some(input) = matches.args.get("input") {
                        println!("从命令行接收输入文件: {:?}", input);
                    }
                }
                Err(e) => {
                    eprintln!("参数解析错误: {}", e);
                    std::process::exit(1);
                }
            }
            
            Ok(())
        })
        .run(tauri::generate_context!())
        .expect("运行Tauri应用时出错");
}

// 处理CLI命令
#[tauri::command]
fn handle_cli(cli: Cli) -> String {
    if cli.debug {
        println!("调试模式已开启");
    }
    
    match &cli.command {
        Some(Commands::Process { output }) => {
            format!("处理命令执行,输出到: {:?}", output)
        }
        Some(Commands::Report { format }) => {
            format!("生成报告,格式为: {:?}", format)
        }
        None => "没有指定子命令".into(),
    }
}

// 处理文件命令
#[tauri::command]
fn process_file(cli: Cli) -> Result<String, String> {
    if let Some(input) = cli.input {
        // 这里添加实际的文件处理逻辑
        Ok(format!("成功处理文件: {}", input))
    } else {
        Err("未指定输入文件".to_string())
    }
}

// 交互式CLI命令
#[tauri::command]
fn interactive_cli(cli: Cli, window: Window) {
    if cli.debug {
        window.emit("cli-event", "调试模式已开启").unwrap();
    }
    
    // 其他交互逻辑
    window.emit("cli-event", "命令已接收").unwrap();
}

4. 前端代码 (src/main.js)

import { invoke, listen } from '@tauri-apps/api/tauri';

// 监听CLI事件
async function setupCliListener() {
  await listen('cli-event', (event) => {
    console.log('收到CLI事件:', event.payload);
  });
}

// 执行CLI命令
async function executeCliCommand() {
  try {
    const args = {
      debug: true,
      input: "data.txt",
      command: {
        name: "process",
        output: "result.txt"
      }
    };
    
    // 调用Rust命令
    const result = await invoke('handle_cli', { cli: args });
    console.log('CLI结果:', result);
    
    // 处理文件
    const fileResult = await invoke('process_file', { 
      cli: { input: "data.txt" } 
    });
    console.log('文件处理结果:', fileResult);
    
    // 交互式命令
    await invoke('interactive_cli', { 
      cli: { debug: true },
      window: window 
    });
    
  } catch (error) {
    console.error('CLI错误:', error);
  }
}

// 初始化
setupCliListener();
document.getElementById('run-cli').addEventListener('click', executeCliCommand);

5. HTML界面 (src/index.html)

<!DOCTYPE html>
<html>
<head>
  <title>Tauri CLI 示例</title>
</head>
<body>
  <h1>Tauri CLI 集成示例</h1>
  <button id="run-cli">执行CLI命令</button>
  <div id="output"></div>
  <script src="main.js"></script>
</body>
</html>

使用说明

  1. 构建和运行应用:
cargo tauri dev
  1. 命令行使用:
# 显示帮助
./my-tauri-app --help

# 使用CLI功能
./my-tauri-app --debug --input data.txt process --output result.txt
  1. 图形界面使用:
  • 点击"执行CLI命令"按钮触发前端调用
  • 查看控制台输出结果

注意事项

  1. 确保Tauri环境和Rust工具链已正确安装
  2. 跨平台测试时注意路径分隔符的差异
  3. 生产环境应考虑更完善的错误处理和日志记录
  4. 复杂CLI应用建议将命令逻辑拆分到独立模块
回到顶部