Node fires 'close' for spawned external application immediately (macOS only) - node.js

My Electron application needs to open an external program and wait for it to be closed before reacting again. In Windows this works fine, but macOS has some problems.
So my code for apple is
const cp = require('child_process');
let child;
child = cp.exec('open -a Keynote \"'+pathToFile+'\"'), function(error, stdout, stderr){
if(error) {
throw error;
}
}
child.on('close', function () {
//do something when external application is closed
}
The problem is, that for some reason the process sends the close event immediately after the application is launched. Is there any way to monitor if Keynote is still opened in macOS, or is it just a bug?

Ok. I found out. If anyone stumbles into the same Problem: It needs to be opened with -WParameter. So
cp.exec('open -a Keynote \"'+pathToFile+'\"' +' -W')
does the trick.

Related

Run Linux command from Angular 4 component

Requirement is to fetch the output of a shell script's after running it from the Angular 4 component at the beginning during compilation i.e. just before the website is launched. I have already gone through the threads in stackoverflow i.e. 49700941 and 41637166.
From the first thread i tried to use the below code, but getting error:
Module not found: Error: Can't resolve 'child_process' in 'app/component ...'
const exec = require('child_process').exec; // Can't resolve 'child_process' error coming from this line
exec('/home/myDir/init_setup.sh', (err, stdout, stderr) => {
if (err){
console.error(err);
return;
};
console.log(stdout);
console.log(stderr);
/**
remaining logics
*/
});
Please let me know if I need to import some library explicitly or not to avoid this error.
The modern browsers opens the webpage in isolated sandbox so they have have no access to clients' computers.
Imagine the damage that could be done if a black hat could run batch script on computer that opens his webpage.
The only way to run the script is to run the desktop application on client's machine.
The example code you provided is Node.js code, the desktop framework that user have to install on his machine and run the code intentionally. There's (fortunately!) no way to run it remotely via webpage.

How do I restart a Node.js server internally in the script on global error?

I've been browsing around but to no success. I've found some npm packages like nodemon and forever but documentation doesn't explain how to call a restart inside the script properly.
I've found this code snippet on another question but I'm not using Express or other frameworks since the script is using a pulling service not a response one.
This is code I've made so far using internal Node.js dependencies but no luck.
'use strict'
process.on('uncaughtException', (error) => {
console.error('Global uncaughtException error caught')
console.error(error.message)
console.log('Killing server with restart...')
process.exit(0)
})
process.on('exit', () => {
console.log('on exit detected')
const exec = require('child_process').exec
var command = 'node app.js'
exec(command, (error, stdout, stderr) => {
console.log(`error: ${error.message}`)
console.log(`stdout: ${stdout}`)
console.log(`stderr: ${stderr}`)
})
})
setTimeout(() => {
errorTriggerTimeBomb() // Dummy error for testing triggering uncaughtException
}, 3000)
Just to note I'm running the server on Termux, a Linux terminal app for android. I know it's better to run from desktop but I'm always at a WiFi or mobile data area and that I don't like leaving my PC on overnight.
A typical restart using something like nodemon or forever would be triggered by calling process.exit() in your script.
This would exit the current script and then the monitoring agent would see that it exited and would restart it for you. It's the same principal as if it crashed on its own, but if you're trying to orchestrate it shutting down, you just exit the process and then the monitoring agent will restart it.
I have a home automation server that is being monitored using forever. If it crashes forever will automatically restart it. I also have it set so that at 4am every morning, it will call process.exit() and then forever will automatically restart it. I do this to prevent any memory leak accumulation over a long period of time and 30 seconds of down time in the middle of the night for my application is no big deal.

How to REALLY kill a child_process nodejs

I'm using mocha with Nodejs to test my restApi.
When I run mocha, I tell my test to create a child_process and run the API so I can make requests to it.
The problem is whenever the test exits (finishing or crashing), it seems that the API keeps running on background. I've seen some answers here that instructs to manually kill the child process whenever the main process exits. So I did it like this:
export function startProcess(done) {
const child = spawn('babel-node', ["app.js"]);
child.stdout.on("data", function(data) {
data = data.toString();
// console.log(data.toString());
if(data.indexOf("Server online") > -1) done();
});
child.stderr.on('data', function(err) {
console.log("ERROR: ", err.toString());
});
child.on('exit', function(code) {
console.log("PROPERLY EXITING");
console.log("Child process exited with code", code);
});
process.on('exit', function(code) {
console.log("Killing child process");
child.kill();
console.log("Main process exited with code", code);
});
}
When the main process exits it does log "Killing child process", meaning that child.kill() was indeed called. But if I try to run my test again, when the spawn command gets called, the API throws an error
Error: listen EADDRINUSE :::3300
, meaning that the API is still running and that port address is taken.
So I have to run sudo pkill node to really kill all node process and then npm test works again.
Am I missing something? Is this really the way to achieve what I'm expecting?
I thought about using child_process.exec to run sudo pkill node on my process.on('exit') listener, but that doesnt seem like a smart thing to do.
This is happening both in Mac and Ubuntu.
Any suggestions?
Thanks
"exit" is an event that gets triggered when node finishes it's event loop internally, it's not triggered when you terminate the process externally.
What you're looking for is executing something on a SIGINT.
Have a look at http://nodejs.org/api/process.html#process_signal_events

How to Restart nodeJS screen app without reboot PC

I trying to restart nodejs app which is running in background screen app.
But here i can't do these without reboot my PC. I used forever module but it's start when i reboot my PC but I actually want one button on web-page and when I click on that automatically start node app without restart my PC.
Any One have iDEA about these please let me guide what to Do ?
NOTE : without reboot my system working
You can execute commands from nodejs like this :
nodejs
var child_process = require('child_process');
child_process.exec('forever restart', function callback(error, stdout, stderr) {
// console.log(stdout);
});

running console application from nodejs app using child_process

I'm trying to run instances of console application ( written on cpp ) from nodejs by using child_process .
Here is the code :
function startSingleApp() {
console.log("startSingleApp entered");
var exec = childProcess.exec;
var appOut;
exec("./ConsoleApplication.exe" ,function callback(error, stdout, stderr){
appOut = stdOut;
console.log("started console app");
});
};
And ConsoleApplication4 only prints strings ( cout<<"some string")
Expected behavior : for each instance of ConsoleApplication4 - console window opened and new process created
Actual behavior : no console window , no process create . But "started console app" string printed on console ( from which nodejs app started )
ConsoleApplication.exe located in same folder where nodejs app located
If replace ConsoleApplication.exe by some window app ( notepad or calc) - it works.
The question - what is missing in this code ? Do I need manually catch console out from the consoleapplication ?
Your help will be helpful.
Thaks in advance
If you run a console application from a console, it’s still going to run in the same console. The Windows console is just a convenience that opens automatically when you’re running a console application through Explorer.
You can try it yourself: open cmd.exe first, then run ConsoleApplication.exe. It won’t open a new window; the output will appear beneath your prompt. And then you’ll get another one.
If you want a window to show up, you can run cmd manually:
exec("cmd /c ConsoleApplication.exe", function callback(error, stdout, stderr) {
appOut = stdOut;
console.log("started console app");
});
You can use start to make a new console window like this:
exec("start ConsoleApplication.exe", ....)
and add a line in your C++:
getch();

Resources