tauri 的 command api在mac和windows环境下的区别

1,038 阅读2分钟

tauriCommand api在官网的介绍非常简单。简单到当你碰到问题的时候,你根本不知道该从哪里着手来解决问题。 要想正常使用 Command,必须要先在src-tauri/tauri.conf.json中声明你的命令作用域(scope)。比如官网的例子:

 "shell": {
        "execute": true,
        "sidecar": true,
        "open": true,
        "scope": [{  
            "name": "run-git-commit",  
            "cmd": "git",  
            "args": ["commit", "-m", { "validator": "\\S+" }]  
            }
         ]
      }

在页面中使用的时候:

import { Command } from '@tauri-apps/api/shell'
new Command('run-git-commit', ['commit', '-m', 'the commit message'])

这似乎要求我们要对每一个命令都要实现进行定义,非常繁琐。比如git 的命令有:

git add 
git commit
git branch
git checkout 
git --version
...

所以,我们只需要将scopeargs改为true就可以接受所有参数了,不需要一个一个去定义。

"shell": {
        "execute": true,
        "sidecar": true,
        "open": true,
        "scope": [{  
            "name": "run-git",  
            "cmd": "git",  
            "args": true 
            }
         ]
      }

我一直以为,tauri已经对不同的平台做了兼容处理,也就是同一个Command我在不同的平台应该都是可以直接运行的。但是,在macOSwindows环境打包程序的时候我发现,我还是太天真了。很多东西,还是需要自己来处理的。

我最开始是在macOS环境下开的程序,运行npm -v非常丝滑。scope配置如下:

"shell": {
        "execute": true,
        "sidecar": true,
        "open": true,
        "scope": [{  
            "name": "npm",  
            "cmd": "npm",  
            "args": true 
            }
         ]
      }

在页面中如下使用:

import { Command } from '@tauri-apps/api/shell'
new Command('npm', ['-v']).spawn();

macOS下一切正常,但是到了windows下完全运行不起来,一直报错program not found。查看了官网文档包括rustapi文档都没有相关介绍。在tauri群里问大神们,也没有人回复。

后来我突发奇想,如果是nodejs中的process_child,它会怎么处理?才发现nodejs也有类似的问题,就是在macOS下运行命令正常,但是到了windows下就跑不了。就这个问题,在网上查了下才最终找到个靠谱的方案。

就是将命令改为xxx.cmd,测试了下确实解决了问题。 在scope中如下配置:

"shell": {
        "execute": true,
        "sidecar": true,
        "open": true,
        "scope": [{  
            "name": "npm",  
            "cmd": "npm.cmd",  
            "args": true 
            }
         ]
      }

这样就可以了。当然如果为了兼容macOSwindows最好将两个都注册到scope

"shell": {
        "execute": true,
        "sidecar": true,
        "open": true,
        "scope": [{  
            "name": "npm",  
            "cmd": "npm",  
            "args": true 
            },{  
            "name": "npm.cmd",  
            "cmd": "npm.cmd",  
            "args": true 
            }
         ]
      }

然后在页面中对不同的platform进行兼容。

import { Command } from '@tauri-apps/api/shell';
import { platform } from '@tauri-apps/api/os';
function async runCommand(){
    const platformName = await platform();
    const cmdStr = /^win/i.test(platformName) ? 'npm.cmd' : 'npm';
    await new Command(cmdStr, ['-v']).spawn();
}
runCommand();

不过,也并不是所有的命令都适用这个方法,比如git在两个环境都是一样的直接用git就好,不需要加.cmd