ChesuCR
ChesuCR

Reputation: 9630

How can I kill a child process run by exec on Windows?

I must use the method exec on Nodejs because I need to do some stdout redirections and run more than one command at the same time. So I run the child process like this:

let shell = null;
const child_process = require('child_process')
var command = 'activate python_environment & bokeh serve project_folder/ log/logger.log 2>&1';
shell = child_process.exec(command); 

I need ps-tree to kill the children as I do in the belower code. It works well on Ubuntu. But the problem is that I get an orphan (zombie) process on Windows if I do not kill the children processes.

const psTree = require('ps-tree')
app.on('window-all-closed', function () {
    electron.app.quit()
    if(shell != null){
        psTree(shell.pid, function (err, children) {
            children.map(function (p) {
                process.kill(p.PID);                    
            });
        });
    }
});

The ps-tree module uses the command ps on linux and the command wmic on Windows. So it is crossplatform. But it does not work in my case. Is there a better way to do this?

I was exploring in the ps-tree source code but I found nothing.

I use process.kill because I am using electron as well.

I am afraid I should try to do it manually getting all the processes list with wmic. That is what ps-tree is trying to do.

Note: The module tree-kill did not work on both platforms neither.

Update

Well, I found an ugly workaround. I save my python process PID into an external file through python code os.getpid(). With this I can access to the problematic PID within node like this:

const fs = require('fs'); 
fs.readFile(filePath, 'utf-8', function (err, data) {
    process.kill(parseInt(data, 10));
    app.quit();                
});

Upvotes: 4

Views: 2388

Answers (1)

peter
peter

Reputation: 42192

I answer for Windows because that's the one you have troubles with.

Looking at the command you execute it seems to me your concatenation of two commands could be the culprit, so I would try doing without it.

If you can't using wmic is the best way I know of, the first time you will have to check manually yes. Once you have the select criterium you can close everything automaticly. While the processes are busy run the command wmic process>processes.txt After that using an editor check the file processes.txt and look in the column commandline for a common string for all the processes you want to kill. This will be your select criterium. Since the whole command line that created the process is there with path and parameters this should be no problem.

After that you should be able to close all those processes with the command

wmic process Where "CommandLine Like '%my_select_criterium%'" Call Terminate

I use this technique in a Ruby script that calls a bad behaving java app that I have no controll over.

Upvotes: 2

Related Questions