跳至主要内容

嵌入外部二进制文件

您可能需要嵌入依赖二进制文件才能使应用程序正常工作或防止用户安装其他依赖项(例如 Node.js 或 Python)。我们将此二进制文件称为“辅助”。

要捆绑您选择的二进制文件,您可以将 externalBin 属性添加到 tauri.conf.json 中的 tauri > bundle 对象。

在此处查看有关 tauri.conf.json 配置的更多信息 here

externalBin 需要一个字符串列表,其中包含以绝对路径或相对路径为目标的二进制文件。

下面是一个示例,用于说明配置。这不是一个完整的 tauri.conf.json 文件

{
"tauri": {
"bundle": {
"externalBin": [
"/absolute/path/to/sidecar",
"relative/path/to/binary",
"binaries/my-sidecar"
]
},
"allowlist": {
"shell": {
"sidecar": true,
"scope": [
{ "name": "/absolute/path/to/sidecar", "sidecar": true },
{ "name": "relative/path/to/binary", "sidecar": true },
{ "name": "binaries/my-sidecar", "sidecar": true }
]
}
}
}
}

在指定路径上必须存在一个同名二进制文件和一个 -$TARGET_TRIPLE 后缀。例如,"externalBin": ["binaries/my-sidecar"] 在 Linux 上需要一个 src-tauri/binaries/my-sidecar-x86_64-unknown-linux-gnu 可执行文件。你可以通过查看 rustc -Vv 命令报告的 host: 属性来查找当前平台的目标三元组。

如果 grepcut 命令可用,就像它们在大多数 Unix 系统上应该可用一样,你可以使用以下命令直接提取目标三元组

rustc -Vv | grep host | cut -f2 -d' '

在 Windows 上,你可以使用 PowerShell

rustc -Vv | Select-String "host:" | ForEach-Object {$_.Line.split(" ")[1]}

下面是一个 Node.js 脚本,用于将目标三元组附加到二进制文件

const execa = require('execa')
const fs = require('fs')

let extension = ''
if (process.platform === 'win32') {
extension = '.exe'
}

async function main() {
const rustInfo = (await execa('rustc', ['-vV'])).stdout
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}`
)
}

main().catch((e) => {
throw e
})

从 JavaScript 运行它

在 JavaScript 代码中,导入 shell 模块上的 Command 类并使用 sidecar 静态方法。

请注意,你必须配置允许列表以启用 shell > sidecar 并配置 shell > scope 中的所有二进制文件。

import { Command } from '@tauri-apps/api/shell'
// alternatively, use `window.__TAURI__.shell.Command`
// `binaries/my-sidecar` is the EXACT value specified on `tauri.conf.json > tauri > bundle > externalBin`
const command = Command.sidecar('binaries/my-sidecar')
const output = await command.execute()

从 Rust 运行它

在 Rust 方面,从 tauri::api::process 模块导入 Command 结构

// `new_sidecar()` expects just the filename, NOT the whole path like in JavaScript
let (mut rx, mut child) = Command::new_sidecar("my-sidecar")
.expect("failed to create `my-sidecar` binary 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) = event {
window
.emit("message", Some(format!("'{}'", line)))
.expect("failed to emit event");
// write to stdin
child.write("message from Rust\n".as_bytes()).unwrap();
}
}
});

请注意,你必须启用process-command-api Cargo 特性(一旦你更改了配置,Tauri 的 CLI 将为你执行此操作)

# Cargo.toml
[dependencies]
tauri = { version = "1", features = ["process-command-api", ...] }

传递参数

你可以像运行普通 Command 一样向 Sidecar 命令传递参数(请参阅 限制对 Command API 的访问)。

首先,在 tauri.conf.json 中定义需要传递给 Sidecar 命令的参数

{
"tauri": {
"bundle": {
"externalBin": [
"/absolute/path/to/sidecar",
"relative/path/to/binary",
"binaries/my-sidecar"
]
},
"allowlist": {
"shell": {
"sidecar": true,
"scope": [
{
"name": "binaries/my-sidecar",
"sidecar": true,
"args": [
"arg1",
"-a",
"--arg2",
{
"validator": "\\S+"
}
]
}
]
}
}
}
}

然后,要调用 sidecar 命令,只需将所有参数作为数组传递即可

import { Command } from '@tauri-apps/api/shell'
// alternatively, use `window.__TAURI__.shell.Command`
// `binaries/my-sidecar` is the EXACT value specified on `tauri.conf.json > tauri > bundle > externalBin`
// notice that the args array matches EXACTLY what is specified on `tauri.conf.json`.
const command = Command.sidecar('binaries/my-sidecar', [
'arg1',
'-a',
'--arg2',
'any-string-that-matches-the-validator',
])
const output = await command.execute()

在 Sidecar 上使用 Node.js

Tauri sidecar 示例演示了如何使用 sidecar API 在 Tauri 上运行 Node.js 应用程序。它使用 pkg 编译 Node.js 代码,并使用上面的脚本运行它。