嵌入外部二进制文件
你可能需要嵌入外部二进制文件以向你的应用添加其他功能,或阻止用户安装其他依赖(例如 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" ] }}
:::note 注意
相对路径是相对于 src-tauri
目录中的 tauri.conf.json
文件而言的。因此 binaries/my-sidecar
将代表 <PROJECT ROOT>/src-tauri/binaries/my-sidecar
。
¥The relative paths are relative to the tauri.conf.json
file which is in the src-tauri
directory.
So binaries/my-sidecar
would represent <PROJECT ROOT>/src-tauri/binaries/my-sidecar
.
:::
要使外部二进制文件在每个受支持的体系结构上工作,指定路径上必须存在具有相同名称和 -$TARGET_TRIPLE
后缀的二进制文件。例如,"externalBin": ["binaries/my-sidecar"]
需要 Linux 上的 src-tauri/binaries/my-sidecar-x86_64-unknown-linux-gnu
可执行文件或 Mac OS 上带有 Apple Silicon 的 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.
你可以通过查看以下命令报告的 host:
属性来找到当前平台的 -$TARGET_TRIPLE
后缀:
¥You can find your current platform’s -$TARGET_TRIPLE
suffix by looking at the host:
property reported by the following command:
rustc -Vv
如果 grep
和 cut
命令可用(它们应该在大多数 Unix 系统上可用),你可以使用以下命令直接提取目标三元组:
¥If the grep
and cut
commands are available, as they should on most Unix systems, you can extract the target triple directly with the following command:
rustc -Vv | grep host | cut -f2 -d' '
在 Windows 上,你可以改用 PowerShell:
¥On Windows you can use PowerShell instead:
rustc -Vv | Select-String "host:" | ForEach-Object {$_.Line.split(" ")[1]}
以下是将目标三元组附加到二进制文件的 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 rustInfo = execSync('rustc -vV');const targetTriple = /host: (\S+)/g.exec(rustInfo)[1];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.
从 Rust 运行
¥Running it from Rust
:::note 注意
请首先按照 shell 插件指南 正确设置和初始化插件。如果插件未初始化和配置,示例将无法运行。
¥Please follow the shell plugin guide first to set up and initialize the plugin correctly. Without the plugin being initialized and configured the example won’t work.
:::
在 Rust 方面,导入 tauri_plugin_shell::ShellExt
特性并在 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;
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); window .emit("message", Some(format!("'{}'", line))) .expect("failed to emit event"); // write to stdin child.write("message from Rust\n".as_bytes()).unwrap(); } }});
:::note 注意
sidecar()
函数只需要文件名,而不是 externalBin
数组中配置的整个路径。
¥The sidecar()
function expects just the filename, NOT the whole path configured in the externalBin
array.
给定以下配置:
¥Given the following configuration:
{ "bundle": { "externalBin": ["binaries/app", "my-sidecar", "../scripts/sidecar"] }}
执行 sidecar 的适当方法是调用 app.shell().sidecar(name)
,其中 name
是 "app"
、"my-sidecar"
或 "sidecar"
,而不是 "binaries/app"
。
¥The appropriate way to execute the sidecar is by calling app.shell().sidecar(name)
where name
is either "app"
, "my-sidecar"
or "sidecar"
instead of "binaries/app"
for instance.
:::
你可以将此代码放在 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.
从 JavaScript 运行
¥Running it from JavaScript
在运行 sidecar 时,Tauri 要求你授予 sidecar 在子进程上运行 execute
或 spawn
方法的权限。要授予此权限,请转到文件 <PROJECT ROOT>/src-tauri/capabilities/default.json
并将下面的部分添加到权限数组中。不要忘记根据前面提到的相对路径命名你的 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 } ] }, "shell:allow-open" ]}
:::note 注意
使用 shell:allow-execute
标识符是因为 sidecar 的子进程将使用 command.execute()
方法启动。要使用 command.spawn()
运行它,你需要将标识符更改为 shell:allow-spawn
或向数组添加另一个条目,其结构与上面的相同,但标识符设置为 shell:allow-spawn
。
¥The shell:allow-execute
identifier is used because the sidecar’s child process will be started using the command.execute()
method. To run it with command.spawn()
, you need to change the identifier to shell:allow-spawn
or add another entry to the array with the same structure as the one above, but with the identifier set to shell:allow-spawn
.
:::
在 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();
:::note 注意
提供给 Command.sidecar
的字符串必须与 externalBin
配置数组中定义的字符串之一匹配。
¥The string provided to Command.sidecar
must match one of the strings defined in the externalBin
configuration array.
:::
传递参数
¥Passing arguments
你可以像运行普通 命令 一样将参数传递给 Sidecar 命令。
¥You can pass arguments to Sidecar commands just like you would for running normal Command.
参数可以是静态的(例如 -o
或 serve
),也可以是动态的(例如 <file_path>
或 localhost:<PORT>
)。你按照调用它们的确切顺序定义参数。静态参数按原样定义,而动态参数可以使用正则表达式定义。
¥Arguments can be either static (e.g. -o
or serve
) or dynamic (e.g. <file_path>
or localhost:<PORT>
). 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 } ] }, "shell:allow-open" ]}
:::note 注意
如果你要从 Tauri v1 迁移,Tauri v2 CLI 中的 migrate
命令应该会为你处理这个问题。阅读 自动迁移 了解更多信息。
¥If you are migrating from Tauri v1, the migrate
command in Tauri v2 CLI should take care of this for you. Read Automated Migration for more.
:::
然后,要调用 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号