How to trigger batch file in node js - javascript

I have a batch file which contains many jar files separated by semicolon :
%~d0
cd %~dp0
java -Xms256M -Xmx1024M -cp .;../lib/routines.jar;../lib/accessors-smart-1.1.jar;../lib/advancedPersistentLookupLib-1.0.jar; test_sample_connector.test_connector_0_1.TEST_connector --context=Default %*
When I call this batch in NodeJS I am getting the following error :
SyntaxError: Unexpected token %
But this batch file works fine if I run in command prompt.
Here is my node js code:
const { spawn } = require('child_process');
const bat = spawn('cmd.exe',['/c','../config/TEST_connector_0.1/TEST_connector/TEST_connector_run.bat']);
bat.stdout.on('data', (data) => {
console.log(data.toString());
});
bat.stderr.on('data', (data) => {
console.log(data.toString());
});
bat.on('exit', (code) => {
console.log(`Child exited with code ${code}`);
});

Related

How to execute a python script via javascript file in an electronjs app?

I am trying to call and execute a python script via the following javascript code in an electronjs app
function getProgramstatus(){
const { exec } = require('child_process');
exec('python python\\getProgramstatus.py', (error, stdout, stderr) => {
});
let jsonData = require('.\\js\\programstatus.json');
let itemData = JSON.stringify(jsonData);
let programstatus = JSON.parse(itemData);
sessionStorage.setItem('programstatus check', programstatus.status);
}
The goal of the python script is to write a value at a json file.
data1={
"status": "12",
"time" : time.ctime(start)
}
json_object = json.dumps( data1, indent = 4)
with open('..\js\programstatus.json', 'w') as outfile:
outfile.write(json_object)
#print("2")
sys.exit("2")
When i execute the python script via terminal it writes at json file, but when i call it from javascript it doen't write at json file. Any ideas;
Try outputting the response for hints, like this:
function getProgramstatus(){
const { exec } = require('child_process');
exec('python python\\getProgramstatus.py', (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.log(`stdout: ${stdout}`);
console.error(`stderr: ${stderr}`);
});
let jsonData = require('.\\js\\programstatus.json');
let itemData = JSON.stringify(jsonData);
let programstatus = JSON.parse(itemData);
sessionStorage.setItem('programstatus check', programstatus.status);
}
And please share the output.
Also the code execution continues while getProgramstatus.py is still running, you want to use execSync / move the code below exec inside the callback or create a promise, so that let jsonData = require('.\\js\\programstatus.json'); gets executed when the python script has finished.
I found the answer, why the json file was not written when the python script was called by the application and not by me at the terminal.
The problem is the folder/file location.
It should be relative to the main.js of the electron app.
So I changed the following:
with open('..\js\programstatus.json', 'w') as outfile:
outfile.write(json_object)
To:
with open('.\js\programstatus.json', 'w') as outfile:
outfile.write(json_object)
and work fine.

How can I integrate python with nodejs

I want to use python scripts with my Node.JS server, but whenever I run the node server, the python script doesn't run. It starts the server but no python runs. I think it's in this part of the code but I'm not exactly sure.
My index.js:
app.post("/readPython", (request, response) => {
var dataToSend;
const python = spawn('python', ['python/cookie.py'], "Kevin");
python.stdout.on('data', function (data) {
dataToSend = data.toString();
});
python.stderr.on('data', data => {
console.error(`stderr: ${data}`);
});
python.on('exit', (code) => {
console.log(`child process exited with code ${code}, ${dataToSend}`);
response.sendFile(`${__dirname}/html/result.html`);
});
});
My python script:
import sys
print("Hello World!")
sys.stdout.flush()
I don't know exactly what I should expect but whatever it is, the script isn't running. Any help?
the 3rd argument (options) in spawn() should be an object. I am assuming you are trying to send Kevin as argument.
It should be like
const python = spawn('python', ['helloworld.py',"Kevin"]);
python.stdout.on('data', (data)=> {
console.log(data.toString());
});

Node child process spawn not executing command

I am trying to execute a child process command to convert a file from a format to another using FFmpeg. I have FFmpeg installed in my system and in the same code I am able to successfully merge a video and a file using cp.spawn. The next step would be to convert the file in the desired format, but the process is immediately exiting with code 1, without giving any errors or outputs.
Here's the code:
const cp = require('child_process');
const ffmpeg = require('ffmpeg-static');
const process = cp.spawn(ffmpeg, [
'-loglevel', '8', '-hide_banner',
'-i', 'output.webm', "output.ogg",
], {
windowsHide: false,
});
process.on('error', (err) => {
console.log('Failed to start subprocess.', error);
});
process.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
process.stderr.setEncoding("utf8")
process.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
})
process.on('close', (code) => {
console.log(`child process exited with code ${code}`);
});
The file "output.webm" is in the current working directory. The only output that I'm getting is: child process exited with code 1, and nothing else happens.

Is there a way to get 'live' output lines from a python script spawned by child_process.execFile without flushing stdout every time?

I am trying to get the lines a ('never ending') python script puts into stdout. But currently my code would only log something to the console when the python process exits. Is there a way I can get the 'live' output of the python script line by line?
spawn_child.js:
let execFile = require("child_process").execFile;
var child = execFile("python3", ["PATH_TO_FILE"]);
child.stdout.on("data", data=>{
console.log(data.toString());
});
child.stderr.on("data", data=>{
console.log(data.toString());
});
child.on("exit", code=>{
console.log("Child exited with code "+code);
});
The python file:
from time import sleep
while True:
sleep(3)
print("test")
Edit: It works when using a nodejs script instead of a python script
change python script to
import time
import sys
while True:
time.sleep(1)
print("test")
sys.stdout.flush()
and increase the buffer size of the child process
const child = execFile("python", ["./runner.py"], {
detached: true,
maxBuffer: 10 * 1024 * 1024 * 1024
});
or you can do it without the flushing to stdout with python-shell
const { PythonShell } = require('python-shell');
let pyshell = new PythonShell('runner.py');
pyshell.on('message', function (message) {
console.log(message);
});
pyshell.end(function (err, code, signal) {
if (err) throw err;
console.log('The exit code was: ' + code);
console.log('The exit signal was: ' + signal);
console.log('finished');
});
Use spawn instead of execFile, dont forget options shell and stdio.
const spawn = require("child_process").spawn;
const child = spawn("python3", ["file.py"], {shell: true, stdio: 'inherit'});
child.on('data', function(data) {
console.log(data);
});
child.on('close', function(code) {
console.log('Child process exited with exit code '+code);
});
You can also add cwd option.
Was trying to implement something similar inside a NextJS application and wanted live output from my python script and using python-shell had the same issue that it was only giving me output when the process existed and I ended up using node-pty instead which worked as expected:
import { spawn } from "node-pty"
const pyProcess = spawn("python", ["path/to/python/script"], {
name: 'xterm-color',
cols: 80,
rows: 30,
cwd: process.cwd(),
});
pyProcess.on('data', function (data: { toString: () => any; }) {
console.log(data.toString());
});
pyProcess.on('exit', (code: any) => {
console.log(`child process exited with code ${code}`);
});

explorer.exe doesn't open correct folder when ran programmatically inside WSL

I'm trying to open explorer.exe from a Node.js script running inside WSL Ubuntu 20.04. The issue I've encountered is that explorer.exe never opens the folder I'd like it to. Instead of WSL user's home directory it opens my Windows user's Documents folder. What should I do to make explorer.exe open the folder I want?
Here's what I've tried:
The script first defines a function execShellCommand that promisifies exec. Then self-executing function first converts process.env.HOME to a Windows path with wslpath. Then it executes explorer.exe with the converted path as a parameter.
#!/usr/bin/node
const execShellCommand = async cmd => {
const exec = require('child_process').exec
return new Promise((resolve, reject) => {
exec(cmd, (error, stdout, stderr) => {
if (error) {
console.warn(error)
}
resolve(stderr ? stderr : stdout)
})
})
}
;(async () => {
const path = await execShellCommand(`wslpath -w "${process.env.HOME}"`)
console.log({ path })
await execShellCommand(`explorer.exe ${path}`)
})()
The output I get when I run my script in WSL
$ ./script.js
{ path: '\\\\wsl$\\Ubuntu-20.04\\home\\user\n' }
Error: Command failed: explorer.exe \\wsl$\Ubuntu-20.04\home\user
at ChildProcess.exithandler (child_process.js:308:12)
at ChildProcess.emit (events.js:315:20)
at maybeClose (internal/child_process.js:1048:16)
at Process.ChildProcess._handle.onexit (internal/child_process.js:288:5) {
killed: false,
code: 1,
signal: null,
cmd: 'explorer.exe \\\\wsl$\\Ubuntu-20.04\\home\\user\n'
}
explorer.exe does run regardless of the error shown in the output. The weird part is that if I run the same command my script tries to run (explorer.exe \\\\wsl$\\Ubuntu-20.04\\home\\user\n) directly in WSL terminal explorer.exe does open the folder I want it to. Trimming the new line at the end of the path doesn't help.
I think you have to do some additional escaping on the backslashes that are produced by wslpath. The code below works for me, meaning it opens the correct directory in Windows Explorer.
Note: it does still throw the error you mentioned, which I think is due to the way node exits rather than anything wrong w/the execution of explorer.exe; I'm not a node expert by any stretch.
#!/usr/bin/node
const execShellCommand = async cmd => {
const exec = require('child_process').exec
return new Promise((resolve, reject) => {
exec(cmd, (error, stdout, stderr) => {
if (error) {
console.warn(error)
}
resolve(stderr ? stderr : stdout)
})
})
}
;(async () => {
let path = await execShellCommand(`wslpath -w "${process.env.HOME}"`)
console.log("before", {path});
path = path.replace(/\\/g,"\\\\");
console.log("after", {path});
await execShellCommand(`explorer.exe ${path}`)
})()
Even cleaner than replacing backslashes, I think this will work for you by resolving the $HOME variable directly into your command line:
await execShellCommand(`explorer.exe "$(wslpath -w $HOME)"`);

Categories