Creator 插件开发如何调用子进程

开发项目用的工具插件,需要调用第三方的工具

举个例子:

系统安装了lame工具,在终端命令行窗口调用lame --help能正常输出结果。
创建一个插件,在main.js里使用

    child_process.execFile("lame",["--help"],function(error,stdout,stderr)
    {
        if (error)
        {
            Editor.log(error);
            return;
        }
        Editor.log(stdout);
        Editor.log(stderr);
    })

会报 { Error: spawn lame ENOENT 错误,换成spawn和exec也是错误。

然后我新建一个main2.js文件,写上上面的代码,命令行用node main2.js可以正常输出

然后,把插件代码写成/usr/local/bin/lame,creator可以正常输出。

我猜测问题应该是creator 的electron模块执行node模块无法识别环境变量或者执行用户权限不同,不可能调用第三方都写全路径吧,所以求官方建议的最佳实践方法

你可以用 child_process.spawn,这个 API 封装的浅一点,例如

    var child = spawn('lame', [
      'rebuild',
      '--target='+target,
      '--arch='+arch,
      '--dist-url='+disturl
    ], {
      stdio: 'inherit'
    });
    child.stdout.on('data', function(data) {
        // data.toString
    });
    child.on('exit', function() {
      // ...
    });

还是不行,我测了一下,在Creator环境执行 process.env跟在命令行终端里执行process.env结果完全不一样。两者的用户权限有差异,creator是不是用了自己的一套环境变量?

命令行执行:

process.env
{ TERM_PROGRAM: ‘Apple_Terminal’,
SHELL: ‘/bin/bash’,
TERM: ‘xterm-256color’,
TMPDIR: ‘/var/folders/sq/bvsym9j11dqgmkdp3lkrbk5w0000gn/T/’,
GRADLE_HOME: ‘/Users/xxx/Documents/Android/gradle-2.14.1’,
Apple_PubSub_Socket_Render: ‘/private/tmp/com.apple.launchd.0ZXyKOvu5z/Render’,
TERM_PROGRAM_VERSION: ‘361.1’,
ANDROID_SDK_ROOT: ‘/Users/xxx/Documents/Android/sdk’,
OLDPWD: ‘/Users/xxx’,
TERM_SESSION_ID: ‘8C7A3DC9-6DC2-4222-A956-7D3CEFEC73E0’,
USER: ‘xxx’,
ANDROID_NDK_ROOT: ‘/Users/xxx/Documents/Android/android-ndk-r10e’,
SSH_AUTH_SOCK: ‘/private/tmp/com.apple.launchd.6tV3rLdm12/Listeners’,
__CF_USER_TEXT_ENCODING: ‘0x1F5:0x19:0x34’,
PATH: ‘/opt/local/bin:/opt/local/sbin:/usr/local/bin:/Library/Frameworks/Python.framework/Versions/3.6/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/xxx/Documents/Android/sdk/platform-tools:/Users/xxx/Documents/Android/sdk:/Users/xxx/Documents/Android/android-ndk-r10e:/Users/xxx/apache-ant-1.10.1/bin:/Users/xxx/Documents/Android/gradle-2.14.1/bin’,
PWD: ‘/Applications/CocosCreator.app’,
XPC_FLAGS: ‘0x0’,
XPC_SERVICE_NAME: ‘0’,
SHLVL: ‘1’,
HOME: ‘/Users/xxx’,
ANT_ROOT: ‘/Users/xxx/apache-ant-1.10.1/bin’,
LOGNAME: ‘xxx’,
LC_CTYPE: ‘UTF-8’,
NDK_ROOT: ‘/Users/xxx/Documents/Android/android-ndk-r10e’,
SECURITYSESSIONID: ‘186a8’,
_: ‘/usr/local/bin/node’ }

creator

process.env { TMPDIR: ‘/var/folders/sq/bvsym9j11dqgmkdp3lkrbk5w0000gn/T/’,
__CF_USER_TEXT_ENCODING: ‘0x1F5:0x19:0x34’,
SHELL: ‘/bin/bash’,
HOME: ‘/Users/xxx’,
Apple_PubSub_Socket_Render: ‘/private/tmp/com.apple.launchd.0ZXyKOvu5z/Render’,
SSH_AUTH_SOCK: ‘/private/tmp/com.apple.launchd.6tV3rLdm12/Listeners’,
PATH: ‘/usr/bin:/bin:/usr/sbin:/sbin’,
LOGNAME: ‘xxx’,
XPC_SERVICE_NAME: ‘com.cocos.creator.320352’,
USER: ‘xxx’,
XPC_FLAGS: ‘0x0’,
GOOGLE_API_KEY: ‘AIzaSyAQfxPJiounkhOjODEO5ZieffeBv6yft2Q’ }

上面的用户我替换成xxx

这个问题应该是 process.env 中没有加入 /usr/local/bin/ 导致。至于 process.env 是否需要和终端执行环境一样,得和其他人商量一下。目前只能先写全路径来解决。

执行环境不同不是 Creator 引发的,应该是桌面程序和终端程序本来就有的差异。
我也不知道有什么比较好的解决方法,可以参考这个帖子 https://discuss.atom.io/t/not-able-to-spawn-npm-modules-from-electron-package-in-os-x-solved/18905

let child_process = require(‘child_process’);
child_process.execFile(“grunt”, [“up-hall”],{cwd:"/Users/dabai/BasicGameMode"}, function (error, stdout, stderr) {
if (error) {
Editor.log(error);
return;
}
Editor.log(stdout);
Editor.log(stderr);
})直接贴代码更直观