嵌入外部二进制文件

您可能需要嵌入依赖的二进制文件,以使应用程序正常运行,或防止用户安装额外的依赖文件(如 Node.js 或 Python)。我们称这种二进制文件为 sidecar

要打包所选的二进制文件,可以在 tauri.conf.json 中的 tauri > bundle 对象中添加 externalBin 属性。

点击此处查看有关 tauri.conf.json 配置的更多信息。

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 静态方法。

请注意,您必须配置 allowlist 以启用 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", ...] }

传递参数

您可以向 Sidecar 命令传递参数,就像运行普通命令一样(请参阅 "限制命令 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 代码,并使用上述脚本运行它。