繁体   English   中英

如何通过child_process.spawn()执行本地安装的Node.js应用程序?

[英]How to execute locally installed Node.js application by child_process.spawn()?

我想通过child_process.spawn执行Electron应用程序:

import ChildProcess, {ChildProcess as ChildProcess__type} from 'child_process';
const childProcess: ChildProcess__type = ChildProcess.spawn(
        'electron',
        ['ProjectInitializer__ElectronMain.js'],
        { cwd: __dirname } // current project root
    );

我收到Error: spawn electron ENOENT错误。 Electron已本地安装,AFAIK是一个很好的做法。 同样, electron ProjectInitializer__ElectronMain.js可以工作,它可以从我的项目目录中执行此控制台命令。

遵循频繁投票的ENOENT错误调试指南 ,我得到了原因: process.env.PATH没有目录,其中包括electron

我对PATH变量了解不多,所以我无法回答该变量中必须包含什么,什么不是。 但是我想问的是:如何执行本地安装(在node_modules )的Node.js应用程序(如electron )?

顺便说一句 ,被称为改进的child_process可以child_process运行电子程序(更新:版本2.xx已经不运行):

import executeExternalCommand, { ExecaReturnValue } from 'execa';

try {
  await executeExternalCommand(
      'electron',
      ['ProjectInitializer__ElectronMain.js'],
      { cwd: __dirname }
  );
} catch (error) {
  console.error(error);
}

不知何故,多亏{ cwd: __dirname }execa v 1.xx知道应该在哪里找到电子。 不幸的是, execa社区太小,文档也很少,因此停止使用它。

附加信息

我如何运行具有spawn参数的Node.js脚本

通过命令创建的my-library init

在package.json中:

"bin": {
  "my-library": "bin/my-library"
}

bin/my-library (无文件扩展名)中:

#!/usr/bin/env node

require('../CLI').interpretConsoleCommandAndExecute(process.argv);

CLI.js我解析了console命令,如果它是my-library init ,我将尝试执行

const childProcess: ChildProcess__type = ChildProcess.spawn(
   'electron',
   [ 'ProjectInitializer__ElectronMain.js' ],
   { cwd: __dirname }
);

console.log(process.env)输出

下面的输出用于PhpStorm内置控制台,但是在其他控制台(例如cmder)中,输出是不同的。

{ FPS_BROWSER_APP_PROFILE_STRING: 'Internet Explorer',
  CommonProgramFiles: 'C:\\Program Files\\Common Files',
  PROMPT: '$P$G',
  SESSIONNAME: 'Console',
  COMPUTERNAME: 'MSI',
  OneDriveConsumer: 'D:\\OneDrive',
  __INTELLIJ_COMMAND_HISTFILE__:
   'C:\\Users\\i\\.PhpStorm2019.1\\config\\terminal\\history\\history-34',
  SystemDrive: 'C:',
  NUMBER_OF_PROCESSORS: '12',
  LOGONSERVER: '\\\\MSI',
  TEMP: 'C:\\Users\\i\\AppData\\Local\\Temp',
  TMP: 'C:\\Users\\i\\AppData\\Local\\Temp',
  HOMEPATH: '\\Users\\i',
  PATHEXT: '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JSE;.WSF;.WSH;.MSC',
  USERNAME: 'i',
  ProgramFiles: 'C:\\Program Files',
  USERDOMAIN_ROAMINGPROFILE: 'MSI',
  LOCALAPPDATA: 'C:\\Users\\i\\AppData\\Local',
  TERMINAL_EMULATOR: 'JetBrains-JediTerm',
  PROCESSOR_IDENTIFIER: 'Intel64 Family 6 Model 158 Stepping 10, GenuineIntel',
  DriverData: 'C:\\Windows\\System32\\Drivers\\DriverData',
  APPDATA: 'C:\\Users\\i\\AppData\\Roaming',
  ALLUSERSPROFILE: 'C:\\ProgramData',
  USERDOMAIN: 'MSI',
  OS: 'Windows_NT',
  PROCESSOR_LEVEL: '6',
  ProgramData: 'C:\\ProgramData',
  ComSpec: 'C:\\Windows\\system32\\cmd.exe',
  PROCESSOR_ARCHITECTURE: 'AMD64',
  FPS_BROWSER_USER_PROFILE_STRING: 'Default',
  SystemRoot: 'C:\\Windows',
  PROCESSOR_REVISION: '9e0a',
  OneDrive: 'D:\\OneDrive',
  PSModulePath:
   'C:\\Program Files\\WindowsPowerShell\\Modules;C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\Modules',
  PATH:
   'D:\\PhpStorm\\InHouseDevelopment\\my-library\\node_modules\\.bin;C:\\ProgramData\\DockerDesktop\\version-bin;C:\\Program Files\\Docker\\Docker\\Resources\\bin;C:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\iCLS\\;C:\\Program Files
\\Intel\\Intel(R) Management Engine Components\\iCLS\\;C:\\Windows\\system32;C:\\Windows;C:\\Windows\\System32\\Wbem;C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C:\\Windows\\System32\\OpenSSH\\;C:\\Program Files (x86)\\NVIDIA Corporation\\PhysX\\Common;C:\\Pro
gram Files\\Intel\\WiFi\\bin\\;C:\\Program Files\\Common Files\\Intel\\WirelessCommon\\;C:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\DAL;C:\\Program Files\\Intel\\Intel(R) Management Engine Components\\DAL;C:\\Program Files (x86)\\Intel\\I
ntel(R) Management Engine Components\\IPT;C:\\Program Files\\Intel\\Intel(R) Management Engine Components\\IPT;C:\\Program Files (x86)\\Common Files\\Acronis\\VirtualFile\\;C:\\Program Files (x86)\\Common Files\\Acronis\\VirtualFile64\\;C:\\Program Files (x86)\\Com
mon Files\\Acronis\\FileProtector\\;C:\\Program Files (x86)\\Common Files\\Acronis\\FileProtector64\\;C:\\Program Files (x86)\\Common Files\\Acronis\\SnapAPI\\;C:\\Program Files\\nodejs\\;C:\\Program Files\\Git\\cmd;C:\\Program Files (x86)\\Yarn\\bin\\;C:\\Users\\t
okug\\AppData\\Local\\Microsoft\\WindowsApps;C:\\Users\\i\\AppData\\Roaming\\npm;C:\\Users\\i\\AppData\\Local\\Yarn\\bin;C:\\texlive\\2019\\bin\\win32',
  'ProgramFiles(x86)': 'C:\\Program Files (x86)',
  USERPROFILE: 'C:\\Users\\i',
  windir: 'C:\\Windows',
  ProgramW6432: 'C:\\Program Files',
  configsetroot: 'C:\\Windows\\ConfigSetRoot',
  'CommonProgramFiles(x86)': 'C:\\Program Files (x86)\\Common Files',
  PUBLIC: 'C:\\Users\\Public',
  HOMEDRIVE: 'C:',
  CommonProgramW6432: 'C:\\Program Files\\Common Files' }

尝试执行ChildProcess.spawn('env')

在Php Strorm控制台中,它会导致常见的Error: spawn env ENOENT

正如聊天中所讨论的,您收到的错误通常是由于您试图运行的可执行文件不可用而引起的。

现在有多种原因可能导致可执行文件不可用

  1. 可执行文件根本不在系统上的任何位置
  2. 可执行文件在其中,但不在系统的PATH变量定义的文件夹中
  3. 可执行文件在当前目录中,但是运行进程的目录上下文不同

要修复#1#2您只需在系统PATH中全局安装可执行文件

要修复#3您可以做两件事。 添加当前目录的路径( { cwd: __dirname} )以及可执行文件的相对路径

const childProcess: ChildProcess__type = ChildProcess.spawn( 
Path.resolve(__dirname, 'node_modules/.bin/electron'), 
[ Path.resolve(__dirname, 'ProjectInitializer__ElectronMain.js') ], 
{ cwd: __dirname} 
); 

要么

const childProcess: ChildProcess__type = ChildProcess.spawn( 
'./node_modules/.bin/electron'), 
[ Path.resolve(__dirname, 'ProjectInitializer__ElectronMain.js') ], 
{ cwd: __dirname} 
); 

要么

const childProcess: ChildProcess__type = ChildProcess.spawn( 
'node_modules/.bin/electron', 
[ './ProjectInitializer__ElectronMain.js' ], 
{ cwd: __dirname} 
); 

如果您决定覆盖PATH环境变量,则可以通过传递带有更多值的env参数来做到这一点

const childProcess: ChildProcess__type = ChildProcess.spawn( 
'node_modules/.bin/electron', 
[ './ProjectInitializer__ElectronMain.js' ], 
{ cwd: __dirname, env: {....}} 
); 

您可以使用process.env的现有环境变量,然后对其进行更新,并将其传递给env参数

您可能需要指定电子命令的完整路径,因为它不在您的路径上。

如果您从项目根目录运行脚本,则电子程序可能位于./node_modules/.bin/electron ,如果它们打包了应用程序以这种方式运行。

我猜您的替代库默认情况下会检查node_modules。

另一种选择是确保电子在您的路径中,但是这需要更新您的系统配置,这对于图书馆来说是很奇怪的。

编辑:具有路径的呼叫示例:

const childProcess: ChildProcess__type = ChildProcess.spawn(
   'node_modules/.bin/electron',
   [ 'ProjectInitializer__ElectronMain.js' ],
   { cwd: __dirname }
);

我还将在该过程中添加一些愚蠢的日志记录,因此您知道该过程失败的原因:

function log(data) {
    console.log("" + data)
}
child_process.stdout.on('data', log)
child_process.stderr.on('data', log)
child_process.on('close', log)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM