Execute bat file using node js - node.js

I have written code to execute bat file using nodejs, but it is restricting me to place the bat file at the same location where package.json file is present and it is not accepting absolute path.
I am using the following code:
const { spawn } = require('child_process');
const bat = spawn('cmd.exe', ['/c','coma.bat']);
bat.stdout.on('data', (data) => {
console.log('data is : '+data.toString());
});
bat.stderr.on('data', (data) => {
console.error('error is : '+data.toString());
});
bat.on('exit', (code) => {
console.log(`Child exited with code ${code}`);
});

it accepts full path (if this is the question):
const { spawn } = require('child_process');
const bat = spawn('cmd.exe', ['/c','C:\\scripts\\somescript.bat']);

Related

How to make spawned process know it's not writing to a terminal (nodejs)

I'm writing a little wrapper to the lzma command in Linux but the program refuses to write to stdout because it believes to be in an interactive terminal:
lzma: Compressed data cannot be written to a terminal
This is my code in js
// Compress a given string using the lzma program, and return the compressed contents.
const { spawn } = require('child_process')
const compress = str => new Promise((resolve, reject) => {
const lzma = spawn('lzma', ["-z", "-c", "-9"],
{ stdio: [process.stdin, process.stdout, process.stderr] })
lzma.on('error', err => {
// console.log(`Failed to start lzma: ${err}`)
reject(err)
})
lzma.on('exit', (code, signal) => {
if (code) {
// console.log(`lzma process exited with code ${code}`)
reject(code)
}
else if (signal) {
// console.log(`lzma process exited with signal ${signal}`)
reject(signal)
}
else {
// console.log(`lzma process exited successfully`)
resolve(compressed)
}
})
lzma.stdin.write(str)
lzma.stdin.end()
let compressed = ''
lzma.stdout.on('data', data => { compressed += data })
})
module.exports = compress
How do I override this behavior?
Try changing line 9 to:
{ stdio: ["pipe", "pipe", "inherit"] })
lzma.stdin and lzma.stdout won't do anything unless they're connected to a pipe. "inherit" means that if lzma writes to stderr, you'll see it on the calling process's stderr.
See the node docs for more info.

how to set temporary JDK Path using nodeJs child-process module

I am taking the JDK path from user input and want to set that path as temporary path using nodeJS spawn, so that I can use that temporary path in my .bat file from session.
I am doing this to run my .bat file with dynamic JDK path:
child_process=require('child_process')
const child = child_process.spawn('cmd.exe', ['/c', 'set PATH=D:\\jdk-18.0.1.1\\bin']);
child.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
child.stderr.on('data', (data) => {
console.error(`stderr: ${data}`);
});
child.on('close', (code) => {
console.log(`child process exited with code ${code}`);
});

Why command runs in terminal but not in extension calls?

If in a terminal I run git flow release publish '1.0.0' it is executed successfully.
If I use child_process.spawn in a test.js and then run it with node ./test.js file it also works fine.
But when I use child_process.spawn inside VS Code extension it produces error
fatal: could not read Username for 'https://github.com': No such device or address
If I edit .git/config and add my name https//$myname#github.com...... then error is
fatal: could not read Password for 'https://github.com': No such device or address.
Here is my code same in test file and VS Code
const spawn = require("child_process").spawn;
let cmd = 'git';
let args = ['flow', 'release', 'publish', '0.2.8'];
// let args = ['flow', 'release', 'delete', '-f', '-r', '0.2.8'];
const child = spawn(cmd, args);
let stdout = [];
let stderr = [];
child.stdout?.on('data', (data) => {
console.log(`[gitflow] Stdout ${data}`);
stdout.push(data.toString());
});
child.stderr?.on('data', (data) => {
console.log(`[gitflow] Stderr ${data}`);
stderr.push(data.toString());
});
child.on('error', err => {
console.log(`[gitflow] Error "${cmd} ${args?.join(" ")}" returned`, err);
});
child.on('spawm', err => {
console.log(`[gitflow] Spawn "${cmd} ${args?.join(" ")}" returned`, err);
});
child.on('exit', code => {
console.log(`[gitflow] Exit "${cmd} ${args?.join(" ")} exited`, code);
});
child.on('close', retc => {
console.log(`[gitflow] Command "${cmd}"`, retc, stderr, stdout);
});

Node.js child_process STDOUT not showing progressbar

I've a problem with displaying the progressbar of a process executed by child_process spawn in a discord bot.
CLI Output:
2021-09-16 16:11:03 Welcome to Minecraft Overviewer version 0.17.39 (2402e41)!
2021-09-16 16:11:03 Generating textures...
2021-09-16 16:12:52 Preprocessing...
2021-09-16 16:15:14 Rendering 228498 total tiles.
99% [===================================================================================================================================================================================================== ] 228494 17.65t/s eta 00h 00m 00s
2021-09-16 19:50:57 Rendering complete!
When using the child_process spawn I get every output except for the progressbar.
Node script:
const child_process = require('child_process');
const command = "python";
const arguments = ["./Minecraft-Overviewer/overviewer.py", "--config=./world.py"]
var child = child_process.spawn(command, arguments, {
encoding: 'utf8',
shell: true
});
child.on('error', (error) => {
message.channel.send('Error!\r\n' + error);
});
child.stdout.setEncoding('utf8');
child.stdout.on('data', (data) => {
data = data.toString();
message.channel.send(`STDOUT: ${data}`);
});
child.stderr.setEncoding('utf8');
child.stderr.on('data', (data) => {
message.channel.send(`DATA: ${data}`);
});
child.on('close', (code) => {
//Here you can get the exit code of the script
switch (code) {
case 0:
message.channel.send('Process exited.');
break;
}
});
Any ideas on how I can catch the progressbar as well?
Many thanks in advance!

Killing a Shell

I'm not sure this is a bug or feature, but when killing a shell (using kill -9 <pid>) it doesn't exit the process, as in it calls the exit event but all code continues running. Here is my code
// index.js
const { spawn } = require("child_process");
const deploy = spawn(`node server`, {
shell: true,
});
console.log(deploy.pid); // I use this to get the PID so i can use the kill command
deploy.stdout.on("data", (data) => {
console.log(data.toString());
});
deploy.stderr.on("data", (data) => {
console.log(data.toString());
});
deploy.on("exit", (code) => {
console.log("exit");
});
// server.js
const app = require("express")();
app.use("/", (req, res) => {
console.log("debug");
res.send("Hello, World");
});
app.listen(8000, () => console.log("Site Online"));
According to the documents, using the sh command on Linux with the -c flag, 1) Fixes the problem of it not closing, 2) Allows you to run multiple commands without the shell option that causes the problem in the first place.
Example:
const deploy = spawn("sh", ["-c", `node server && ls`], {
stdio: ["inherit", "inherit", "inherit"],
});

Resources