How do I run an external file within Gulp? - javascript

At the moment I'm using the "gulp-run" plugin to run a .bat file. That plugin has now been deprecated and I'm looking for the best way to execute the .bat now.
Current code:
var gulp = require('gulp');
var run = require('gulp-run');
module.exports = function() {
run('c:/xxx/xxx/runme.bat').exec();
};
Solution as per #cmrn suggestion:
var exec = require('child_process').exec;
var batchLocation = 'c:/xxx/xxx/runme.bat';
gulp.task('task', function (cb) {
exec(batchLocation, function (err, stdout, stderr) {
console.log(stdout);
console.log(stderr);
cb(err);
});
})

If you need to run the script as part of a gulp stream (i.e. in pipe()) you can use gulp-exec. If not, you can just use child_process.exec as described in the gulp-exec README, copied below.
var exec = require('child_process').exec;
gulp.task('task', function (cb) {
exec('ping localhost', function (err, stdout, stderr) {
console.log(stdout);
console.log(stderr);
cb(err);
});
})

Related

BATCH: How can I close running batch file by the name using node.js

I want to know how can I close running batch file using Child process or anything in node.js
This is an example for exec in child process
const { exec, spawn } = require('child_process');
exec('my.bat', (err, stdout, stderr) => {
if (err) {
console.error(err);
return;
}
console.log(stdout);
});
In order to kill the spawned process when using 'child_process', you need to return the created ChildProcess reference, in this case by exec().
You can then kill the process using it's own API, ie. doing childProcess.kill().
Full example:
const { exec, spawn } = require('child_process');
const childProcess = exec('my.bat', (err, stdout, stderr) => {
// explicitly kill the process
childProcess.kill();
if (err) {
console.error(err);
return;
}
console.log(stdout);
});
Find more details in the node.js docs
exec()
childProcess.kill()
If anyone is running into the issue that the batch file is not killable with .kill() or process.kill(processToKill.pid) or is starting another exe that is independent of the batch file, one solution that worked for me was to check the exe/process name I want to kill in the task manager and kill it with the (Windows) cmd command "taskkill /IM name.exe".
In code that looks like the following:
Executing the extra program (.bat, .exe, .lnk):
const systemprocess = require("child_process");
exampleVariable = systemprocess.exec("C:/ProgramData/Microsoft/Windows/Start Menu/Programs/Accessories/Snipping Tool.lnk", (err, stdout, stderr) => {
if (err) {
console.error(err);
return;
}
console.log(stdout);
});
Killing the process:
systemprocess.exec(`taskkill /IM SnippingTool.exe`, (err, stdout, stderr) => {
if (err) {
throw err
}
if (stdout) {
console.log('stdout', stdout)
}
console.log('stderr', err)
});
Though if you execute another exe with spawn you should be able to kill it with varaibleNameOfChildProcess.kill(); like #Kworz answer suggests.
Instead of using exec use spawn, you might be able te retreive the PID generated by the bat file execution. Call process.kill(PID) to kill the running bat file
var spawn = require('child_process').spawn;
var child = spawn('my.bat', {detached: true});
process.kill(child.pid);

/bin/sh: 1: node: not found with child_process.exec

I tried to run a nodejs script with the built in child_process module and it works fine until i give it options. Specially when i add the env property to the options object.
let exec = require('child_process').exec;
exec('node random.js', { env: {} }, (err) => {
console.log(err);
})
Then i get this error: /bin/sh: 1: node: not found.
I have node installed with nvm, maybe that is the cause, but don't know why.
If you exec a new shell from your script this don't have the same environment of the parent shell (your script).
So you have to provide all the needed environment.
In your case I see 2 way you could do.
First: you create a node command with the full path:
let exec = require('child_process').exec;
let node_cmd = '/path/to/my/node/node';
exec(node_cmd + ' random.js', { env: {} }, (err) => {
console.log(err);
});
So you could use env variables to handle the path, or just change it when you need.
Second, pass the path variable to the command:
let exec = require('child_process').exec;
let env_variables = 'PATH='+process.env.PATH;
let cmd = env_variables + ' node random.js';
exec(cmd, { env: {} }, (err) => {
console.log(err);
});
Another way is using the dotenv package.

How to use npm scripts within javascript

I need a complete guide or a good reference material to solve the running module commands within javascript file problem.
Say that I often run:
$ npm run webpack-dev-server --progress --colors -- files
How can I run this within a javascript file and execute with
$ node ./script.js
script.js
var webpackDevServer = require('webpack-dev-server');
// need help here
var result = webpackDevServer.execute({
progress: true,
colors: true,
}, files);
Answer
I do something like this for my Webpack bundles. You can simply use child_process.spawn to execute command-line programs and handle the process in a node script.
Here's an example:
var spawn = require('child_process').spawn
// ...
// Notice how your arguments are in an array of strings
var child = spawn('./node_modules/.bin/webpack-dev-server', [
'--progress',
'--colors',
'<YOUR ENTRY FILE>'
]);
child.stdout.on('data', function (data) {
process.stdout.write(data);
});
child.stderr.on('data', function (data) {
process.stdout.write(data);
});
child.on('exit', function (data) {
process.stdout.write('I\'m done!');
});
You can handle all of the events you like. This is a fairly powerful module that allows you to view the process' PID (child.pid) and even kill the process whenever you choose (child.kill()).
Addendum
A neat trick is to throw everything into a Promise. Here's a simplified example of what my version of script.js would look like:
module.exports = function () {
return new Promise(function (resolve, reject) {
var child = spawn('./node_modules/.bin/webpack', [
'-d'
]);
child.stdout.on('data', function (data) {
process.stdout.write(data);
});
child.on('error', function (data) {
reject('Webpack errored!');
});
child.on('exit', function () {
resolve('Webpack completed successfully');
});
});
}
Using this method, you can include your script.js in other files and make this code synchronous in your build system or whatever. The possibilities are endless!
Edit The child_process.exec also lets you execute command-line programs:
var exec = require('child_process').exec
// ...
var child = exec('webpack-dev-server --progress --colors <YOUR ENTRY FILES>',
function(err, stdout, stderr) {
if (err) throw err;
else console.log(stdout);
});
The accepted answer doesn't work on Windows and doesn't handle exit codes, so here's a fully featured and more concise version.
const spawn = require('child_process').spawn
const path = require('path')
function webpackDevServer() {
return new Promise((resolve, reject) => {
let child = spawn(
path.resolve('./node_modules/.bin/webpack-dev-server'),
[ '--progress', '--colors' ],
{ shell: true, stdio: 'inherit' }
)
child.on('error', reject)
child.on('exit', (code) => code === 0 ? resolve() : reject(code))
})
}
path.resolve() properly formats the path to the script, regardless of the host OS.
The last parameter to spawn() does two things. shell: true uses the shell, which appends .cmd on Windows, if necessary and stdio: 'inherit' passes through stdout and stderr, so you don't have to do it yourself.
Also, the exit code is important, especially when running linters and whatnot, so anything other than 0 gets rejected, just like in shell scripts.
Lastly, the error event occurs when the command fails to execute. When using the shell, the error is unfortunately always empty (undefined).
Do you need it to be webpack-dev-server? There is an equivalent webpack-dev-middleware for running within node/express:
'use strict';
let express = require('express');
let app = new express();
app.use(express.static(`${__dirname}/public`));
let webpackMiddleware = require('webpack-dev-middleware');
let webpack = require('webpack');
let webpackConfig = require('./webpack.config.js');
app.use(webpackMiddleware(webpack(webpackConfig), {}));
app.listen(3000, () => console.log(`Server running on port 3000...`));
https://github.com/webpack/webpack-dev-middleware

Execute an exe file using node.js

I don't know how to execute an exe file in node.js. Here is the code I am using. It is not working and doesn't print anything. Is there any possible way to execute an exe file using the command line?
var fun = function() {
console.log("rrrr");
exec('CALL hai.exe', function(err, data) {
console.log(err)
console.log(data.toString());
});
}
fun();
you can try execFile function of child process modules in node.js
Refer:
http://nodejs.org/api/child_process.html#child_process_child_process_execfile_file_args_options_callback
You code should look something like:
var exec = require('child_process').execFile;
var fun =function(){
console.log("fun() start");
exec('HelloJithin.exe', function(err, data) {
console.log(err)
console.log(data.toString());
});
}
fun();
If the exe that you want to execute is in some other directory, and your exe has some dependencies to the folder it resides then, try setting the cwd parameter in options
var exec = require('child_process').execFile;
/**
* Function to execute exe
* #param {string} fileName The name of the executable file to run.
* #param {string[]} params List of string arguments.
* #param {string} path Current working directory of the child process.
*/
function execute(fileName, params, path) {
let promise = new Promise((resolve, reject) => {
exec(fileName, params, { cwd: path }, (err, data) => {
if (err) reject(err);
else resolve(data);
});
});
return promise;
}
Docs
If you are using Node Js or any front end framework that supports Node JS (React or Vue)
const { execFile } = require('child_process');
const child = execFile('chrome.exe', [], (error, stdout, stderr) => {
if (error) {
throw error;
}
console.log(stdout);
});
If the .exe file is located somewhere in the machine, replace chrome.exe with the path to the application you want to execute
e.g "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"
const child = execFile('C:\Program Files (x86)\Google\Chrome\Application\chrome.exe', [], (error, stdout, stderr) => {
if (error) {
throw error;
}
console.log(stdout);
});
Did you ever think about using Batch file in this process? I mean start a .bat file using node.js which will start an .exe file in the same time?
just using answers in the top i got this:
Creating a .bat file in exe file's directory
Type in bat file
START <full file name like E:\\Your folder\\Your file.exe>
Type in your .js file:
const shell = require('shelljs')
shell.exec('E:\\Your folder\\Your bat file.bat')

Automate npm and bower install with grunt

I have a node / angular project that uses npm for backend dependency management and bower for frontend dependency management. I'd like to use a grunt task to do both install commands. I haven't been able to figure out how to do it.
I made an attempt using exec, but it doesn't actually install anything.
module.exports = function(grunt) {
grunt.registerTask('install', 'install the backend and frontend dependencies', function() {
// adapted from http://www.dzone.com/snippets/execute-unix-command-nodejs
var exec = require('child_process').exec,
sys = require('sys');
function puts(error, stdout, stderr) { console.log(stdout); sys.puts(stdout) }
// assuming this command is run from the root of the repo
exec('bower install', {cwd: './frontend'}, puts);
});
};
When I cd into frontend, open up node, and run this code from the console, this works fine. What am I doing wrong in the grunt task?
(I also tried to use the bower and npm APIs, but couldn't make that work either.)
To install client side components during npm install at the same time than server side libs, you can add in your package.json
"dependencies": {
...
"bower" : ""
},
"scripts": {
...
"postinstall" : "bower install"
}
I prefer to make the difference between install and test/build
You need to tell grunt that you're using an async method (.exec) by calling the this.async() method, getting a callback, and calling that when exec is done.
This should work:
module.exports = function(grunt) {
grunt.registerTask('install', 'install the backend and frontend dependencies', function() {
var exec = require('child_process').exec;
var cb = this.async();
exec('bower install', {cwd: './frontend'}, function(err, stdout, stderr) {
console.log(stdout);
cb();
});
});
};
See Why doesn't my asynchronous task complete?
FYI, here is where i am for now.
You could also have taken the problem another way, i.e. let npm handle the execution of bower, and ultimately let grunt handle npm. See Use bower with heroku.
grunt.registerTask('install', 'install the backend and frontend dependencies', function() {
var async = require('async');
var exec = require('child_process').exec;
var done = this.async();
var runCmd = function(item, callback) {
process.stdout.write('running "' + item + '"...\n');
var cmd = exec(item);
cmd.stdout.on('data', function (data) {
grunt.log.writeln(data);
});
cmd.stderr.on('data', function (data) {
grunt.log.errorlns(data);
});
cmd.on('exit', function (code) {
if (code !== 0) throw new Error(item + ' failed');
grunt.log.writeln('done\n');
callback();
});
};
async.series({
npm: function(callback){
runCmd('npm install', callback);
},
bower: function(callback){
runCmd('bower install', callback);
}
},
function(err, results) {
if (err) done(false);
done();
});
});
Grunt task that does just this job (as per Sindre's solution above):
https://github.com/ahutchings/grunt-install-dependencies
Grunt task that does the bower install command :
https://github.com/yatskevich/grunt-bower-task
also , you can use
https://github.com/stephenplusplus/grunt-bower-install
to auto inject your dependencies into the index.html file

Categories

Resources