简体   繁体   English

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

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

I want to execute the Electron 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
    );

I got Error: spawn electron ENOENT error. 我收到Error: spawn electron ENOENT错误。 Electron has been installed locally, AFAIK is the good practice. Electron已本地安装,AFAIK是一个很好的做法。 Also, electron ProjectInitializer__ElectronMain.js works, it to execute this console command from my project directory. 同样, electron ProjectInitializer__ElectronMain.js可以工作,它可以从我的项目目录中执行此控制台命令。

Following frequently up-voted ENOENT error debugging guidance , I got the cause: there is no directory among process.env.PATH , which includes electron . 遵循频繁投票的ENOENT错误调试指南 ,我得到了原因: process.env.PATH没有目录,其中包括electron

I know about PATH variable not much, so I can not answer what must be in this variable and what is not. 我对PATH变量了解不多,所以我无法回答该变量中必须包含什么,什么不是。 But what I want to ask is: how to execute locally installed (in node_modules ) Node.js applications (like electron )? 但是我想问的是:如何执行本地安装(在node_modules )的Node.js应用程序(如electron )?

By the way, execa which is known as improved child_process runs electron without errors (update: version 2.xx already do not runs): 顺便说一句 ,被称为改进的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);
}

Somehow, thanks to { cwd: __dirname } , the execa v 1.xx knows, where should to find the electron. 不知何故,多亏{ cwd: __dirname }execa v 1.xx知道应该在哪里找到电子。 Unfortunately, execa has too small community and small documentations, so stopped to use it. 不幸的是, execa社区太小,文档也很少,因此停止使用它。

Additional information 附加信息

How I run this Node.js script which has the spawn parameter 我如何运行具有spawn参数的Node.js脚本

By command my-library init which I created. 通过命令创建的my-library init

In package.json: 在package.json中:

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

In bin/my-library (no filename extension): bin/my-library (无文件扩展名)中:

#!/usr/bin/env node

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

In CLI.js I parse the console command, and if it is the my-library init , I'll try to execute CLI.js我解析了console命令,如果它是my-library init ,我将尝试执行

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

console.log(process.env) output console.log(process.env)输出

Below output is for PhpStorm build-in console, however in other consoles, eg in cmder, output is different. 下面的输出用于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' }

Trying to execute ChildProcess.spawn('env') 尝试执行ChildProcess.spawn('env')

In Php Strorm console, it causes familiar Error: spawn env ENOENT . 在Php Strorm控制台中,它会导致常见的Error: spawn env ENOENT

As discussed in the chat, the error you are getting is usually caused by the fact that the executable you are trying to run is not available 正如聊天中所讨论的,您收到的错误通常是由于您试图运行的可执行文件不可用而引起的。

Now there are multiple reasons the executable may not be available 现在有多种原因可能导致可执行文件不可用

  1. The executable is not there at all anywhere on the system 可执行文件根本不在系统上的任何位置
  2. The executable is there but not in the folders defined by system's PATH variable 可执行文件在其中,但不在系统的PATH变量定义的文件夹中
  3. The executable is there in the current directory but the directory context in which the process is being run is different 可执行文件在当前目录中,但是运行进程的目录上下文不同

To fix #1 and #2 you just install the executable globally in system PATH 要修复#1#2您只需在系统PATH中全局安装可执行文件

For fixing #3 you can do two things. 要修复#3您可以做两件事。 Add the path for the current directory ( { cwd: __dirname} ) and also a relative path to executable 添加当前目录的路径( { cwd: __dirname} )以及可执行文件的相对路径

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

or 要么

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

or 要么

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

In case you decide to override the PATH environment variable you can do it passing the env parameters with more values 如果您决定覆盖PATH环境变量,则可以通过传递带有更多值的env参数来做到这一点

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

You can use the existing environment variables from process.env and then update the same, and pass it to env parameter 您可以使用process.env的现有环境变量,然后对其进行更新,并将其传递给env参数

it's likely that you need to specify the full path to the electron command, since it isn't on your path. 您可能需要指定电子命令的完整路径,因为它不在您的路径上。

If you are running your script from your project root, electron is probably at in ./node_modules/.bin/electron , if they packaged up the app to be run that way. 如果您从项目根目录运行脚本,则电子程序可能位于./node_modules/.bin/electron ,如果它们打包了应用程序以这种方式运行。

I would guess that your alternative library checks node_modules by default. 我猜您的替代库默认情况下会检查node_modules。

The alternative would be to ensure electron is in your path, but that requires updating your system configuration, which it would be weird for a library to do. 另一种选择是确保电子在您的路径中,但是这需要更新您的系统配置,这对于图书馆来说是很奇怪的。

Edit: example of call with path: 编辑:具有路径的呼叫示例:

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

I'd also add some dumb logging on the process, so you know why the process failed: 我还将在该过程中添加一些愚蠢的日志记录,因此您知道该过程失败的原因:

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.

相关问题 Node.js:捕获`child_process.spawn`的STDOUT - Node.js: Capture STDOUT of `child_process.spawn` node.js child_process.spawn no stdout除非'inherit' - node.js child_process.spawn no stdout unless 'inherit' 如何在node.js中清除child_process.spawn()上的子进程 - How to clean child processes on child_process.spawn() in node.js 如何在Ubuntu中作为命令或服务运行可执行文件(使用Node.js child_process.spawn())? - How to run executable file in Ubuntu as a command or service (with Node.js child_process.spawn())? 如何在Windows上正确使用node.js child_process.spawn()重定向? - How to correctly use node.js child_process.spawn() redirection on Windows? 如何确保node.js child_process.spawn将错误消息写入控制台 - How to ensure node.js child_process.spawn will write error messages to the console 如何通过Node.js中的child_process.spawn()将长字符串传递给/ dev / stdin? - How do you pipe a long string to /dev/stdin via child_process.spawn() in Node.js? 如何在Node.js中通过child_process.spawn()将长字符串传递给? - How do i pipe a long string to via child_process.spawn() in Node.js? node.js - 如何调整 child_process.spawn() 的标准输出缓冲区大小(又名 highWaterMark)? - node.js - How to adjust the the stdout buffer size (aka highWaterMark) of child_process.spawn()? node.js child_process.spawn-进程运行但事件不触发 - node.js child_process.spawn - process runs but events don't fire
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM