嵌入外部二進制檔案
您可能需要嵌入外部二進制檔案,以將額外功能新增至您的應用程式,或防止使用者安裝額外的依賴(例如 Node.js 或 Python)。我們將此二進制檔案稱為 sidecar
(輔助程式)。
二進制檔案是以任何程式語言編寫的可執行檔。常見的用例是使用 pyinstaller
捆綁的 Python CLI 應用程式或 API 伺服器。
若要捆綁您選擇的二進制檔案,您可以將 externalBin
屬性新增至 tauri > bundle
物件中的 tauri.conf.json
。 externalBin
組態預期一個字串清單,目標為絕對或相對路徑的二進制檔案。
以下是一個 Tauri 組態程式碼片段,用於說明 sidecar 組態
{ "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
可執行檔。
您可以透過查看以下命令回報的 host:
屬性,找到您目前平台的 -$TARGET_TRIPLE
後綴
rustc -Vv
如果 grep
和 cut
命令可用(在大多數 Unix 系統上應該可用),您可以使用以下命令直接提取目標三元組
rustc -Vv | grep host | cut -f2 -d' '
在 Windows 上,您可以使用 PowerShell 來代替
rustc -Vv | Select-String "host:" | ForEach-Object {$_.Line.split(" ")[1]}
這是一個 Node.js 腳本,用於將目標三元組附加到二進制檔案
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}`);
請注意,如果您編譯的架構與其運行的架構不同,則此腳本將無法運作,因此僅將其用作您自己的建置腳本的起點。
從 Rust 執行
在 Rust 端,匯入 tauri_plugin_shell::ShellExt
trait,並在 AppHandle 上呼叫 shell().sidecar()
函數
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(); } }});
您可以將此程式碼放在 Tauri 命令中,以輕鬆傳遞 AppHandle,或者您可以將 AppHandle 的參考儲存在 builder 腳本中,以便在應用程式的其他位置存取它。
從 JavaScript 執行
執行 sidecar 時,Tauri 要求您授予 sidecar 權限,以在子程序上執行 execute
或 spawn
方法。若要授予此權限,請前往檔案 <PROJECT ROOT>/src-tauri/capabilities/default.json
,並將以下章節新增至 permissions 陣列。別忘了根據先前提及的相對路徑命名您的 sidecar。
{ "permissions": [ "core:default", { "identifier": "shell:allow-execute", "allow": [ { "name": "binaries/app", "sidecar": true } ] }, "shell:allow-open" ]}
在 JavaScript 程式碼中,從 @tauri-apps/plugin-shell
模組匯入 Command
類別,並使用 sidecar
靜態方法。
import { Command } from '@tauri-apps/plugin-shell';const command = Command.sidecar('binaries/my-sidecar');const output = await command.execute();
傳遞引數
您可以將引數傳遞給 Sidecar 命令,就像您對執行一般 Command 所做的那樣。
引數可以是靜態(例如 -o
或 serve
)或動態(例如 <file_path>
或 localhost:<PORT>
)。您以您呼叫它們的確切順序定義引數。靜態引數按原樣定義,而動態引數可以使用正則表達式定義。
首先,在 src-tauri/capabilities/default.json
中定義需要傳遞給 sidecar 命令的引數
{ "$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" ]}
然後,若要呼叫 sidecar 命令,只需將所有引數作為陣列傳入即可。
在 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 中
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();
© 2025 Tauri 貢獻者。CC-BY / MIT