嵌入外部二进制文件
你可能需要嵌入外部二进制文件,以向你的应用添加额外功能,或防止用户安装额外的依赖(例如 Node.js 或 Python)。我们将此二进制文件称为 sidecar。
🌐 You may need to embed external binaries to add additional functionality to your application or prevent users from installing additional dependencies (e.g., Node.js or Python). We call this binary a sidecar.
二进制文件是用任何编程语言编写的可执行文件。常见的使用场景是使用 pyinstaller 打包的 Python CLI 应用或 API 服务器。
🌐 Binaries are executables written in any programming language. Common use cases are Python CLI applications or API servers bundled using pyinstaller.
要打包你选择的二进制文件,你可以将 externalBin 属性添加到你的 tauri.conf.json 中的 tauri > bundle 对象。
externalBin 配置期望一个字符串列表,目标是拥有绝对路径或相对路径的二进制文件。
🌐 To bundle the binaries of your choice, you can add the externalBin property to the tauri > bundle object in your tauri.conf.json.
The externalBin configuration expects a list of strings targeting binaries either with absolute or relative paths.
以下是 Tauri 配置片段,用于说明 sidecar 配置:
🌐 Here is a Tauri configuration snippet to illustrate a sidecar configuration:
{ "bundle": { "externalBin": [ "/absolute/path/to/sidecar", "../relative/path/to/binary", "binaries/my-sidecar" ] }}为了使外部二进制文件在每个支持的架构上工作,指定路径上必须存在一个具有相同名称并带有 -$TARGET_TRIPLE 后缀的二进制文件。
例如,"externalBin": ["binaries/my-sidecar"] 需要在 Linux 上有一个 src-tauri/binaries/my-sidecar-x86_64-unknown-linux-gnu 可执行文件,或者在搭载 Apple Silicon 的 Mac OS 上有一个 src-tauri/binaries/my-sidecar-aarch64-apple-darwin 可执行文件。
🌐 To make the external binary work on each supported architecture, a binary with the same name and a -$TARGET_TRIPLE suffix must exist on the specified path.
For instance, "externalBin": ["binaries/my-sidecar"] requires a src-tauri/binaries/my-sidecar-x86_64-unknown-linux-gnu executable on Linux or src-tauri/binaries/my-sidecar-aarch64-apple-darwin on Mac OS with Apple Silicon.
你可以通过运行以下命令找到你当前平台的 -$TARGET_TRIPLE 后缀:
🌐 You can find your current platform’s -$TARGET_TRIPLE suffix by running the following command:
rustc --print host-tuple这会直接输出主机的目标三元组(例如,x86_64-unknown-linux-gnu 或 aarch64-apple-darwin)。
🌐 This directly outputs your host’s target triple (e.g., x86_64-unknown-linux-gnu or aarch64-apple-darwin).
以下是将目标三元组附加到二进制文件的 Node.js 脚本:
🌐 Here’s a Node.js script to append the target triple to a binary:
import { execSync } from 'child_process';import fs from 'fs';
const extension = process.platform === 'win32' ? '.exe' : '';
const targetTriple = execSync('rustc --print host-tuple').toString().trim();if (!targetTriple) { console.error('Failed to determine platform target triple');}fs.renameSync( `src-tauri/binaries/sidecar${extension}`, `src-tauri/binaries/sidecar-${targetTriple}${extension}`);请注意,如果你为与其运行的架构不同的架构进行编译,该脚本将无法工作,因此仅将其用作自己构建脚本的起点。
🌐 Note that this script will not work if you compile for a different architecture than the one its running on, so only use it as a starting point for your own build scripts.
🌐 Running it from Rust
在 Rust 端,导入 tauri_plugin_shell::ShellExt trait 并在 AppHandle 上调用 shell().sidecar() 函数:
🌐 On the Rust side, import the tauri_plugin_shell::ShellExt trait and call the shell().sidecar() function on the AppHandle:
use tauri_plugin_shell::ShellExt;use tauri_plugin_shell::process::CommandEvent;use tauri::Emitter;
let sidecar_command = app.shell().sidecar("my-sidecar").unwrap();let (mut rx, mut child) = sidecar_command .spawn() .expect("Failed to spawn sidecar");
tauri::async_runtime::spawn(async move { // read events such as stdout while let Some(event) = rx.recv().await { if let CommandEvent::Stdout(line_bytes) = event { let line = String::from_utf8_lossy(&line_bytes); app .emit("message", Some(format!("'{}'", line))) .expect("failed to emit event"); // write to stdin child.write("message from Rust\n".as_bytes()).unwrap(); } }});你可以将此代码放在 Tauri 命令中以轻松传递 AppHandle,或者你可以将对 AppHandle 的引用存储在构建器脚本中以在应用的其他位置访问它。
🌐 You can place this code inside a Tauri command to easily pass the AppHandle or you can store a reference to the AppHandle in the builder script to access it elsewhere in your application.
🌐 Running it from JavaScript
运行 sidecar 时,Tauri 要求你授予 sidecar 在子进程上运行 execute 或 spawn 方法的权限。要授予此权限,请转到文件 <PROJECT ROOT>/src-tauri/capabilities/default.json 并将以下部分添加到 permissions 数组中。别忘了按照前面提到的相对路径命名你的 sidecar。
🌐 When running the sidecar, Tauri requires you to give the sidecar permission to run the execute or spawn method on the child process. To grant this permission, go to the file <PROJECT ROOT>/src-tauri/capabilities/default.json and add the section below to the permissions array. Don’t forget to name your sidecar according to the relative path mentioned earlier.
{ "permissions": [ "core:default", { "identifier": "shell:allow-execute", "allow": [ { "name": "binaries/app", "sidecar": true } ] } ]}在 JavaScript 代码中,从 @tauri-apps/plugin-shell 模块导入 Command 类并使用 sidecar 静态方法。
🌐 In the JavaScript code, import the Command class from the @tauri-apps/plugin-shell module and use the sidecar static method.
import { Command } from '@tauri-apps/plugin-shell';const command = Command.sidecar('binaries/my-sidecar');const output = await command.execute();🌐 Passing arguments
你可以像运行普通 命令 一样向 Sidecar 命令传递参数。
🌐 You can pass arguments to Sidecar commands just like you would for running normal Command.
参数可以是静态的(例如 -o 或 serve)或动态的(例如 <file_path> 或 localhost:<PORT>)。值为 true 将允许传递任意参数给命令。false 将禁用所有参数。如果既未设置 true 也未设置 false,则需要按调用顺序定义参数。静态参数按原样定义,而动态参数可以使用正则表达式定义。
🌐 Arguments can be either static (e.g. -o or serve) or dynamic (e.g. <file_path> or localhost:<PORT>). A value of true will allow any arguments to be passed to the command. false will disable all arguments. If neither true or false is set, you define the arguments in the exact order in which you’d call them. Static arguments are defined as-is, while dynamic arguments can be defined using a regular expression.
首先,在 src-tauri/capabilities/default.json 中定义需要传递给 sidecar 命令的参数:
🌐 First, define the arguments that need to be passed to the sidecar command in src-tauri/capabilities/default.json:
{ "$schema": "../gen/schemas/desktop-schema.json", "identifier": "default", "description": "Capability for the main window", "windows": ["main"], "permissions": [ "core:default", { "identifier": "shell:allow-execute", "allow": [ { "args": [ "arg1", "-a", "--arg2", { "validator": "\\S+" } ], "name": "binaries/my-sidecar", "sidecar": true } ] } ]}然后,要调用 sidecar 命令,只需将所有参数作为数组传入即可。
🌐 Then, to call the sidecar command, simply pass in all the arguments as an array.
在 Rust 中:
🌐 In Rust:
use tauri_plugin_shell::ShellExt;#[tauri::command]async fn call_my_sidecar(app: tauri::AppHandle) { let sidecar_command = app .shell() .sidecar("my-sidecar") .unwrap() .args(["arg1", "-a", "--arg2", "any-string-that-matches-the-validator"]); let (mut _rx, mut _child) = sidecar_command.spawn().unwrap();}在 JavaScript 中:
🌐 In JavaScript:
import { Command } from '@tauri-apps/plugin-shell';// notice that the args array matches EXACTLY what is specified in `capabilities/default.json`.const command = Command.sidecar('binaries/my-sidecar', [ 'arg1', '-a', '--arg2', 'any-string-that-matches-the-validator',]);const output = await command.execute();Tauri 中文网 - 粤ICP备13048890号
Nodejs.cn 旗下网站