【Tauri2】036——Sidecar和shell插件 (二)

前言

前面在后端使用了插件shell,这篇就在前端使用一下这个插件

【Tauri2】029------Sidecar和shell插件 (一)-CSDN博客https://blog.csdn.net/qq_63401240/article/details/147262402?spm=1001.2014.3001.5502

正文

前端使用shell插件

@tauri-apps/plugin-shell | Taurihttps://v2.tauri.app/zh-cn/reference/javascript/shell/https://v2.tauri.app/zh-cn/reference/javascript/shell/运行命令

rust 复制代码
pnpm tauri add shell

前端使用插件,从前面的插件fs、opener等经验总结,本质上就两件事

1、权限问题

2、通信函数的使用

简单使用

rust 复制代码
import {Command} from '@tauri-apps/plugin-shell'
export async function useCommand(){
    const cmd=Command.create("ffmpeg",["--version"])
    let a=await cmd.execute()
    console.log(a.stderr)
}

需要设置权限,简单设置一下

rust 复制代码
 {
      "identifier":"shell:allow-execute",
      "allow": [
      {
        "name": "ffmpeg",
        "cmd": "ffmpeg"
      },
      {
        "name": "ffplay",
        "cmd": "ffplay"
      },
      {
        "name": "ffprobe",
        "cmd": "ffprobe"
      }
    ]
    }

结果如下

这个create方法

rust 复制代码
static create(program: string, args?: string | string[]): Command<string>;

是个静态方法,第一个传字符串,第一个参数传字符串或者字符串数组,返回 Command<string>

execute方法就是通信函数,返回ChildProcess,

rust 复制代码
    execute(): Promise<ChildProcess<O>>;

这ChildProcess就是一个接口,字段如下

TypeScript 复制代码
interface ChildProcess<O extends IOPayload> {
    /** Exit code of the process. `null` if the process was terminated by a signal on Unix. */
    code: number | null;
    /** If the process was terminated by a signal, represents that signal. */
    signal: number | null;
    /** The data that the process wrote to `stdout`. */
    stdout: O;
    /** The data that the process wrote to `stderr`. */
    stderr: O;
}

处理执行之后的事情

spawn与事件

笔者先把要使用的权限写出来

rust 复制代码
  {
      "identifier": "shell:allow-spawn",
      "allow": [
        {
          "name": "python",
          "cmd": "python",
          "args": [
            { "validator": "^[\\s\\S]*$" }
          ]
        },
        {
          "name": "ffmpeg",
          "cmd": "ffmpeg",
          "args": [
            { "validator": "^[\\s\\S]*$" }
          ]
        },
        {
          "name":"ffprobe",
          "cmd":"ffprobe",
          "args": [
            { "validator": "^[\\s\\S]*$" },
            { "validator": "^[\\s\\S]*$" }
          ]
        }
      ]
    },
  "shell:allow-stdin-write",

名字和 cmd可以不一样,name是任取的

^[\\s\\S]*$是正则表达式,这能够匹配几乎所有的字符。

可以写具体的。

先试试ffmpeg
rust 复制代码
    const command = Command.create('ffmpeg',["-version"]);
    command.stdout.on('data', (data) => {
        console.log(`stdout: ${data}`);
    });
    command.stderr.on('data', (data) => {
        console.error(`stderr: ${data}`);
    });
    command.on('error', (error) => {
        console.error(`error: ${error}`);
    });
    command.on('close', (code) => {
        console.log(`child process exited with code ${code}`);
    });
    let child=await command.spawn();

上面就是前端用于监控shell的输出事件

打印的结果是成功的,打印的是stdout的输出

使用python
rust 复制代码
 const command = Command.create('python',["-i"]);
    ....
    await child.write("print('hello world')\n");

结果如下,打印了hello world 没有问题

如果没有设置权限或者权限不准确,比如说

rust 复制代码
 {
          "name": "python",
          "cmd": "python"
  },

去掉参数,没有打印结果

运行了,但是没有打印语句的出现。

使用ffprobe,获取MP4信息
rust 复制代码
    const command = Command.create("ffprobe",["-i",
        "C:/Users/26644/Videos/p/2024-01-21-16-35-04.mp4"]);

结果如下 ,成功

如果不满足正则表达式,也会报错,

当然,笔者直接匹配任意字符,不管三七二十一。

spawn会返回Child,如果需要是kill方法,还需要权限kill

rust 复制代码
    "shell:allow-kill"
通信函数

从后端的invoke_handler中或者控制台中

rust 复制代码
.invoke_handler(tauri::generate_handler![
            commands::execute,
            commands::spawn,
            commands::stdin_write,
            commands::kill,
            commands::open
        ])

可以发现有五个通信函数,open一般不使用,因此,就四个

也很简单

1、execute:同步执行一个系统命令,并返回其输出

2、spawn:异步启动一个子进程

3、stdin_write:向已启动的子进程的标准输入

4、kill:强制终止一个正在运行的子进程

使用bun

配置exe

rust 复制代码
    "externalBin": [
      "bin/bun"
    ],

记得改名,编译后

配置权限

{
"identifier": "shell:allow-spawn",
"allow": [
{
"name":"bin/bun",
"sidecar": true
}
]
},

使用

rust 复制代码
export async function useCommand(){
    let cmd=Command.sidecar("bin/bun")
    cmd.stdout.on("data",(data)=>{
        console.log(data.toString())
    })
    cmd.stderr.on("data",(data)=>{
        console.log(data.toString())
    })
    cmd.on("close",(code)=>{
        console.log(`child process exited with code ${code}`);
    })
    let child=await cmd.spawn()
    console.log(child)

}

直接写bun会报错,需要写bin/bun。结果如下

执行TS

一段简单地TS代码,src/utils/test.ts

TypeScript 复制代码
function fibonacci(n: number): number {
    return n <= 1 ? n : fibonacci(n - 1) + fibonacci(n - 2);
}

const result = fibonacci(10);
console.log("Result:", result); 

bun运行结果如下

修改权限,如下

rust 复制代码
  {
      "identifier": "shell:allow-spawn",
      "allow": [
        {
          "name":"bin/bun",
          "args": [
            "run",
            { "validator": "^[\\s\\S]*$" }
          ],
          "sidecar": true
        }
      ]
    },

修改关键代码

rust 复制代码
import {path} from "@tauri-apps/api";    
const tsFilePath = await path.resolve('../src/utils/test.ts');
let cmd=Command.sidecar("bin/bun",["run",tsFilePath])

默认项目的根路径居然是**src-tauri,**需要后退

结果如下

node.js当作sidebar

一段简单地代码backend.js

javascript 复制代码
const express = require('express');
const app = express();
const port = 3000; 

app.get('/', (req, res) => {
    res.send('Hello world');
});

app.listen(port, () => {
    console.log(`Server is running on port ${port}`);
});

实际上可以把node.js变成可执行文件

Node.js 作为 Sidecar | Tauri - Tauri 框架https://v2.tauri.org.cn/learn/sidecar-nodejs/使用的是pkg这个东西

将NodeJS应用程序打包为独立可执行文件(exe)_nodejs打包成exe-CSDN博客https://blog.csdn.net/ouyangtianhan/article/details/136767883这个pkg有要求node的版本,但是笔者node是v23,太高了,没成功。

pkg-fetch/patches/patches.json at main · vercel/pkg-fetchhttps://github.com/vercel/pkg-fetch/blob/main/patches/patches.json

将NodeJS应用程序打包为独立可执行文件(exe)_nodejs打包成exe-CSDN博客https://blog.csdn.net/ouyangtianhan/article/details/136767883如果使用nexe,也要配置配置,笔者也没有成功。

如下报错

❯ nexe backend.js --build
i nexe 5.0.0-beta.4
√ Including dependency: D:\start\src\utils\backend.js
√ Already downloaded...
√ Compiling Node with arguments: nosign,release,x64
√ Finished in 0.421s

Error: vcbuild.bat nosign release x64 exited with code: 1

vcbuild.bat nosign release x64 exited with code: 1 · Issue #799 · nexe/nexehttps://github.com/nexe/nexe/issues/799解决这个报错,从github的链接中可用发现如下命令

nexe backend.js -o test -t windows --build --verbose

笔者看了看,也有很多要求。。。。

需要有Python、NASM、Visual Studio, 当然**,**笔者恰好都有

在编译中还搞一大推东西。我怀疑自己用错了,没编译完

但是这搞得也太麻烦了,不推荐使用。。。。。

将就使用pkg

首先,需要切换node版本,笔者使用volta来管理node版本

Volta - The Hassle-Free JavaScript Tool Managerhttps://volta.sh/如下

❯ volta install node@18
success: installed and set [email protected] (with [email protected]) as default

然后修改backend.js的后缀js改为cjs

打包运行

❯ pkg backend.cjs --target win
> [email protected]

start\src\utils via  v18.20.8 took 5s
❯ node backend.cjs
Server is running on port 3000

没问题。后面在tauri中使用这个exe文件就不必细说了。

总结

前端使用shell,实际上,并没有后端方便。

当然,还有可以的。

看个人需求。

相关推荐
雨笋情缘2 天前
【2025-05-22】centos 离线安装兼容node和npm版本的pm2 和 yarn
linux·npm·centos·node·yarn·pm2
疏狂难除4 天前
【Tauri2】046—— tauri_plugin_clipboard_manager(一)
前端·clipboard·tauri2
Coding的叶子6 天前
React Flow 节点属性详解:类型、样式与自定义技巧
react.js·node·节点·fgai·react agent
疏狂难除22 天前
【Tauri2】035——sql和sqlx
sql·tauri2
疏狂难除1 个月前
【Tauri2】026——Tauri+Webassembly
rust·wasm·tauri2
疏狂难除2 个月前
【Tauri2】013——前端Window Event与创建Window
前端·javascript·rust·react·tauri2
疏狂难除2 个月前
【Tauri2】002——Cargo.toml和入口文件
tauri2
James5062 个月前
Ubuntu平台下安装Node相关环境
前端·javascript·vue.js·node·yarn·pm2·nvm
AJ_Styles2 个月前
pnpm 报错 Error: Cannot find matching keyid 解决
pnpm·node·corepack