child_process.execFile slow to exit
Asked Answered
M

2

10

I have a Node script that calls an external program (PluginManager.exe) this way:

const util = require('util');
const execFile = util.promisify(require('child_process').execFile);

const process = execFile('PluginManager.exe', ['/install']);
process
  .then(({stdout, stderr}) => console.log('done', stdout, stderr))
  .catch(e => console.log(e));

PluginManager.exe takes 8 seconds to execute. My problem is that the Node script keeps running for another 10 more seconds after the child process has exited. I know when PluginManager.exe finishes because I can see it disappear from the Windows Task Manager Process List.

What keeps the Node process running for so long and what can I do to make sure it exits as soon as the child process exits?

Mulcahy answered 4/4, 2018 at 16:42 Comment(7)
Can you try with execFile('PluginManager.exe', ['/install'], {shell: true}) and see if it helps?Cajolery
@TarunLalwani thanks for the suggestion but I get the same result.Mulcahy
Which version of Node are you using?Cajolery
@TarunLalwani version 8.9.1Mulcahy
See if using spawn helps? https://mcmap.net/q/109102/-exec-display-stdout-quot-live-quotCajolery
Does any spawned process have this issue? Is it any exe? It'll be hard to offer a solution if we cannot duplicate it.Volotta
@KevinPeno, Yes it is an exe. Interestingly, it doesn't do it with all exes! I'll do more testing to find a pattern and identify which kind of exe cause that. Thanks for your comment.Mulcahy
N
2

Maybe it's waiting on input and timing out after 10s?

Try closing stdin with .end() as mentioned in https://nodejs.org/api/child_process.html#child_process_subprocess_stdin

(in this usage, you'll need the original return value of execFile, so don't promisify, as per https://mcmap.net/q/135929/-how-to-promisify-node-39-s-child_process-exec-and-child_process-execfile-functions-with-bluebird)

e.g.

const util = require('util');
const execFile = require('child_process').execFile;

const process = execFile(
  'PluginManager.exe', ['/install'], (e, stdout, stderr) => {
    if (e) {
      console.log(e);
    } else {
      console.log('done', stdout, stderr));
    }});
process.stdin.end();
Ns answered 13/4, 2018 at 16:42 Comment(0)
B
0

Have you tried by adding the killSignal option set to something a bit more aggresive?

const process = execFile('PluginManager.exe', ['/install'], {killSignal: 'SIGKILL'});
Borneol answered 13/4, 2018 at 16:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.