Node JS - Cannot Kill Process Executed with Child Process Exec - node.js

We are trying to kill the process of a chrome browser launched with nodes child_process exec command
var process = cp.exec(`"chrome.exe" --app="..."`, () => {}); // working great
But when we try
process.kill(); //nothing happens...
Does the process refer to the chrome window or something else? if not, how can we get a hold of the newly opened chrome window process, PID, etc...?
Any help would be great...
Note - we have tried using the chrome_launcher NPM but it didn't help because we couldn't open chrome in kiosk mode without fullscreen, but this is an issue for a different question...

Try the PID hack
We can start child processes with {detached: true} option so those processes will not be attached to main process but they will go to a new group of processes.
Then using process.kill(-pid) method on main process we can kill all processes that are in the same group of a child process with the same pid group. In my case, I only have one processes in this group.
var spawn = require('child_process').spawn;
var child = spawn('your-command', {detached: true});
process.kill(-child.pid);

I built a cross platform npm package that wraps up spawning and killing child processes from node, give it a try.
https://www.npmjs.com/package/subspawn

I am not able to add comment, so I am saying it directly in the answer:
How to kill process with node js
If you check the link above you need library as follows
https://www.npmjs.com/package/fkill
Usage Example taken from stackoverflow question
const fkill = require('fkill');
fkill(1337).then(() => {
console.log('Killed process');
});
fkill('Safari');
fkill([1337, 'Safari']);
I also found this library to check running processes
https://github.com/neekey/ps

Related

Is that possible to kill the child process in Node.js by new HTTP request

Is there a way to kill the child_process.exec() from previous request by a new request ex
I have part of code like so :
var proc = require('child_process').exec('ffmpeg -i a.mp4 -o b.avi');
scenario like this
request come -> check the exec() is running or not -> if running kill
it->run new exec() -> return !
is that possible to kill this running process by a new HTTP request?
is there a way to set an app status for Node.js and set a flag, then check the flag to stop the process?
In my opinion, you can kill a child process by two ways.
Solution 1:
Use child process object with kill() function like
proc.kill();
Solution 2:
Get process PID from child process and kill it by nodejs process anywhere in your application (execute kill action in HTTP request) like
// Get process's pid and save it somewhere or global variable
let pid = proc.pid;
At next HTTP request comes, you can kill it by:
// Use node process to kill it anywhere by pid
process.kill(pid);
For your information, if you want to check a child process is running or not, try to check my question here Nodejs how to check independently a process is running by PID?

node.js - How to spawn a child process without blocking stdin of parent process?

I'm making an interactive CLI in node (and blessed.js) that spawns child processes every couple of seconds to run some Python scripts. These scripts modify a set of JSON files that the CLI pulls from.
The problem is that the CLI must be able to accept input from the user at all times, and when these child processes are spawned, the stdin of the CLI/parent process appears to be blocked and it looks like the Python scripts are executing in the foreground. Here's the code I'm using to run the Python scripts:
const { spawn } = require("child_process");
function execPythonScript(args) {
return spawn("python3", args, { stdio: "ignore" });
}
execPythonScript(["path_to_script.py"]);
I've also tried running the script as a background process, i.e. execPythonScript(["path_to_script.py", "&"]), but to no avail. Any ideas?
Thanks in advance!
UPDATE:
I'm starting to suspect this is an issue with blessed and not child-process, since I've exhausted all relevant methods (and their arguments) for spawning non-blocking background processes, and the problem still persists.
Each blessed instance uses process.stdin for input by default, but I figured it's possible that the stdin stream gets used up by the child processes, even though I'm spawning them with stdio set to "ignore". So I tried using ttys and instantiating blessed.screen to read from the active terminal (/dev/tty) instead of /dev/stdin:
const ttys = require("ttys");
screen = blessed.screen({
input: ttys.stdin, // Instead of process.stdin
smartCSR: true
});
But it's still blocking...
You also need to detach the process:
spawn("python3", args, { stdio: "ignore", detached: true })
This is a useful primer.

I get a wrong pid with child_process.spawn

I have problem in an Electron app and reduce the problem to a simple testspawn.js run in node
var spawn = require('child_process').spawn,
exp = spawn('explorer', ['d:'],{detached:true}); //same thing detached or not
console.log('Spawned child pid: ' + exp.pid);
When I run node testspawn.js an explorer in the D: directory is showing but the console say: Spawned child pid: 5880.
BUT the Task Manager of Windows say :
As I want at the end kill the explorer when I don't need it anymore, noway to have the right pid. What is the thing I'm missing ? . Completely lost ...
Not exactly sure what electron is doing, but the process you get back is actually the parent of the process you are trying to kill. I was able to successfully kill the "actual" process by using tree-kill. If you want to get the actual pid of the grandchild process you can use something like process-tree to iterate over the process tree.
Further to my last comment, I don't have all the aswers but my case got a workaround ...

How to send "CTRL+C" to child process in Node.js?

I tried to spawn child process - vvp (https://linux.die.net/man/1/vvp). At the certain time, I need to send CTRL+C to that process.
I am expecting that simulation will be interrupted and I get the interactive prompt. And after that I can continue the simulation by send command to the child process.
So, I tried something like this:
var child = require('child_process');
var fs = require('fs');
var vcdGen = child.spawn('vvp', ['qqq'], {});
vcdGen.stdout.on('data', function(data) {
console.log(data.toString())
});
setTimeout(function() {
vcdGen.kill('SIGINT');
}, 400);
In that case, a child process was stopped.
I also tried vcdGen.stdin.write('\x03') instead of vcdGen.kill('SIGINT'); but it isn't work.
Maybe it's because of Windows?
Is there any way to achieve the same behaviour as I got in cmd?
kill only really supports a rude process kill on Windows - the application signal model in Windows and *nix isn't compatible. You can't pass Ctrl+C through standard input, because it never comes through standard input - it's a function of the console subsystem (and thus you can only use it if the process has an attached console). It creates a new thread in the child process to do its work.
There's no supported way to do this programmatically. It's a feature for the user, not the applications. The only way to do this would be to do the same thing the console subsystem does - create a new thread in the target application and let it do the signalling. But the best way would be to simply use coöperative signalling instead - though that of course requires you to change the target application to understand the signal.
If you want to go the entirely unsupported route, have a look at https://stackoverflow.com/a/1179124/3032289.
If you want to find a middle ground, there's a way to send a signal to yourself, of course. Which also means that you can send Ctrl+C to a process if your consoles are attached. Needless to say, this is very tricky - you'd probably want to create a native host process that does nothing but create a console and run the actual program you want to run. Your host process would then listen for an event, and when the event is signalled, call GenerateConsoleCtrlEvent.

Close another process from node on Windows

How can I kill a process from node on Windows?
I'm making a updater. It needs close a windows executable (.exe) to download the updates. (The update process is download and overwrite). I read that this is possible with process.kill(pid[, signal])
But, How can I get the PID of the process if I know the name of the process?
According to the documentation, you simply access the property.
process.kill(process.pid, 'SIGKILL');
This is a theoretical, untested, psuedo function that may help explain what I have in mind
exec('tasklist', (err, out, code) => { //tasklist is windows, but run command to get proccesses
const id = processIdFromTaskList(processName, out); //get process id from name and parse from output of executed command
process.kill(id, "SIGKILL"); //rekt
});
Use node-windows to get pid of process you want to kill so that you can call process.kill. The library also provides an api to kill task.

Resources