Socket
Socket
Sign inDemoInstall

node-windows

Package Overview
Dependencies
17
Maintainers
1
Versions
23
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.0.0-beta.7 to 1.0.0-beta.8

30

lib/binaries.js
var path = require('path'),
bin = path.join(__dirname,'..','bin'),
exec = require('child_process').exec;
bin = path.join(__dirname, '..', 'bin'),
exec = require('child_process').exec;
var params = function(options,callback) {
callback = callback || function(){};
var params = function (options, callback) {
callback = callback || function () { };
options = options || {};
if (typeof options === 'function'){
if (typeof options === 'function') {
callback = options;
options = {};
}
if (typeof options !== 'object'){
if (typeof options !== 'object') {
throw 'Invalid options parameter.';
}
return {options:options,callback:callback};
return { options: options, callback: callback };
}

@@ -42,5 +42,5 @@

*/
elevate: function(cmd,options,callback) {
var p = params(options,callback);
exec('"'+path.join(bin,'elevate','elevate.cmd')+'" '+cmd,p.options,p.callback);
elevate: function (cmd, options, callback) {
var p = params(options, callback);
exec('"' + path.join(bin, 'elevate', 'elevate.cmd') + '" ' + cmd, p.options, p.callback);
},

@@ -69,5 +69,5 @@

*/
sudo: function(cmd,password,options,callback){
sudo: function (cmd, password, options, callback) {
password = password || '';
if (typeof password !== 'string'){
if (typeof password !== 'string') {
callback = options;

@@ -77,5 +77,5 @@ options = password;

}
var p = params(options,callback);
exec(path.join(bin,'sudowin','sudo.exe')+' '+(password !== '' ? '-p '+password:'')+cmd,p.options,p.callback);
var p = params(options, callback);
exec(path.join(bin, 'sudowin', 'sudo.exe') + ' ' + (password !== '' ? '-p ' + password : '') + cmd, p.options, p.callback);
}
}
}
var exec = require('child_process').exec,
bin = require('./binaries');
bin = require('./binaries');

@@ -16,6 +16,6 @@ module.exports = {

*/
isAdminUser: function(callback){
exec('NET SESSION',function(err,so,se){
if (se.length !== 0){
bin.elevate('NET SESSION',function(_err,_so,_se){
isAdminUser: function (callback) {
exec('NET SESSION', function (err, so, se) {
if (se.length !== 0) {
bin.elevate('NET SESSION', function (_err, _so, _se) {
callback(_se.length === 0);

@@ -39,17 +39,17 @@ });

*/
kill: function(pid,force,callback){
if (!pid){
kill: function (pid, force, callback) {
if (!pid) {
throw new Error('PID is required for the kill operation.');
}
if (isNaN(pid)) {
if (typeof isNaN(pid)) {
throw new Error('PID must be a number.')
}
callback = callback || function(){};
if (typeof force == 'function'){
callback = callback || function () { };
if (typeof force == 'function') {
callback = force;
force = false;
}
exec("taskkill /PID "+pid+(force==true?' /f':''),callback);
exec("taskkill /PID " + pid + (force == true ? ' /f' : ''), callback);
},

@@ -65,20 +65,20 @@

*/
list: function(callback,verbose){
list: function (callback, verbose) {
verbose = typeof verbose == 'boolean' ? verbose : false;
exec('tasklist /FO CSV'+(verbose==true?' /V':''),function(err,stdout,stderr){
exec('tasklist /FO CSV' + (verbose == true ? ' /V' : ''), function (err, stdout, stderr) {
var p = stdout.split('\r\n');
var proc = [];
var head = null;
while (p.length > 1){
while (p.length > 1) {
var rec = p.shift();
rec = rec.replace(/\"\,/gi,'";').replace(/\"|\'/gi,'').split(';');
if (head == null){
rec = rec.replace(/\"\,/gi, '";').replace(/\"|\'/gi, '').split(';');
if (head == null) {
head = rec;
for (var i=0;i<head.length;i++){
head[i] = head[i].replace(/ /gi,'');
for (var i = 0; i < head.length; i++) {
head[i] = head[i].replace(/ /gi, '');
}
} else {
var tmp = {};
for (var i=0;i<rec.length;i++){
tmp[head[i]] = rec[i].replace(/\"|\'/gi,'');
for (var i = 0; i < rec.length; i++) {
tmp[head[i]] = rec[i].replace(/\"|\'/gi, '');
}

@@ -92,2 +92,2 @@ proc.push(tmp);

};
};

@@ -33,9 +33,9 @@ /**

var exec = require('child_process').exec,
path = require('path'),
fs = require('fs'),
PermError = 'Permission Denied. Requires administrative privileges.',
wincmd = require('./binaries'),
Logger = require('./eventlog'),
daemonDir = 'daemon',
wrapper = path.resolve(path.join(__dirname,'./wrapper.js'));
path = require('path'),
fs = require('fs'),
PermError = 'Permission Denied. Requires administrative privileges.',
wincmd = require('./binaries'),
Logger = require('./eventlog'),
daemonDir = 'daemon',
wrapper = path.resolve(path.join(__dirname, './wrapper.js'));

@@ -45,5 +45,5 @@ // BEGIN SUPER AWFUL HACK TO GET AROUND WINSW.EXE ISSUE! REPLACE ASAP!!!!

// it continues processing with the "install" method.
var sleep = function(period){
var sleep = function (period) {
var st = new Date().getTime();
while(new Date().getTime() <= st+(period*1000)){}
while (new Date().getTime() <= st + (period * 1000)) { }
return;

@@ -53,3 +53,3 @@ };

// The daemon class
var daemon = function(config){
var daemon = function (config) {

@@ -86,3 +86,3 @@ /**

*/
Object.defineProperties(this,{
Object.defineProperties(this, {
_name: {

@@ -95,3 +95,3 @@ enumerable: false,

_eventlog:{
_eventlog: {
enumerable: false,

@@ -105,6 +105,6 @@ writable: true,

enumerable: false,
get: function(){
get: function () {
var wrapperArgs = [
'--file', this.script,
'--scriptoptions='+this.scriptOptions,
'--scriptoptions=' + this.scriptOptions,
'--log', this.name + ' ' + 'wrapper',

@@ -114,8 +114,7 @@ '--grow', this.grow,

'--maxrestarts', this.maxRestarts,
'--abortonerror', (this.abortOnError==true?'y':'n'),
'--abortonerror', (this.abortOnError == true ? 'y' : 'n'),
'--stopparentfirst', this.stopparentfirst
];
if (this.maxRetries!==null)
{
if (this.maxRetries !== null) {
wrapperArgs.push('--maxretries');

@@ -149,4 +148,4 @@ wrapperArgs.push(this.maxRetries);

enumerable: false,
get: function(){
return this.id+'.exe';
get: function () {
return this.id + '.exe';
}

@@ -175,3 +174,3 @@ },

configurable: false,
value: config.hasOwnProperty('stopparentfirst') ? config.stopparentfirst : false
value: config.stopparentfirst
},

@@ -192,3 +191,3 @@

/**
* @cfg {string} [nodeOptions]
* @cfg {string} [nodeOptions='--harmony']
* Options to be passed to the node process.

@@ -200,9 +199,9 @@ */

configurable: false,
value: config.nodeOptions
value: config.nodeOptions || '--harmony'
},
/**
* @cfg {string} [scriptOptions='']
* Options to be passed to the script.
*/
/**
* @cfg {string} [scriptOptions='']
* Options to be passed to the script.
*/
scriptOptions: {

@@ -279,10 +278,10 @@ enumerable: true,

configurable: false,
value: function(dir){
if (this.script == null || this.name == null){
value: function (dir) {
if (this.script == null || this.name == null) {
throw Error('Script and Name are required but were not provided.');
}
if (dir){
if (dir) {
this._directory = path.resolve(dir);
}
return path.resolve(path.join(this._directory,daemonDir));
return path.resolve(path.join(this._directory, daemonDir));
}

@@ -297,3 +296,3 @@ },

enumerable: true,
get: function(){ return this.directory();}
get: function () { return this.directory(); }
},

@@ -304,3 +303,3 @@

enumerable: false,
get: function(){
get: function () {
if (this._eventlog !== null)

@@ -310,3 +309,3 @@ return this._eventlog;

throw 'No name was specified for the service';
this._eventlog = new Logger(this.name+' Monitor');
this._eventlog = new Logger(this.name + ' Monitor');
return this._eventlog;

@@ -335,4 +334,4 @@ }

enumerable: false,
get: function(){return this._name;},
set: function(value){this._name = value;}
get: function () { return this._name; },
set: function (value) { this._name = value; }
},

@@ -343,4 +342,4 @@

enumerable: true,
get: function(){
return this.name.replace(/[^\w]/gi,'').toLowerCase();
get: function () {
return this.name.replace(/[^\w]/gi, '').toLowerCase();
}

@@ -453,3 +452,3 @@ },

sudo: {
enumerable:false,
enumerable: false,
writable: true,

@@ -514,18 +513,18 @@ configurable: false,

configurable: false,
value: function(dir){
if (this.script == null || this.name == null){
value: function (dir) {
if (this.script == null || this.name == null) {
throw Error('Script and Name are required but were not provided.');
}
if (this.exists){
if (this.exists) {
var missing = false;
if (!fs.existsSync(path.join(this.root,this._exe))){
this.log.warn('The main executable is missing or cannot be found ('+path.join(this.root,this._exe)+')');
if (!fs.existsSync(path.join(this.root, this._exe))) {
this.log.warn('The main executable is missing or cannot be found (' + path.join(this.root, this._exe) + ')');
missing = true;
}
if (!fs.existsSync(path.join(this.root,this.id+'.xml'))){
this.log.warn('The primary configuration file is missing or cannot be found ('+path.join(this.root,this.id+'.xml')+')');
if (!fs.existsSync(path.join(this.root, this.id + '.xml'))) {
this.log.warn('The primary configuration file is missing or cannot be found (' + path.join(this.root, this.id + '.xml') + ')');
missing = true;
}
if (missing.length > 0){
if (missing.length > 0) {
this.emit('invalidinstallation');

@@ -541,3 +540,3 @@ return;

if (typeof dir === 'function'){
if (typeof dir === 'function') {
callback = dir;

@@ -549,11 +548,11 @@ dir = null;

// If the output directory does not exist, create it.
fs.exists(dir,function(exists){
if (!exists){
fs.exists(dir, function (exists) {
if (!exists) {
fs.mkdirSync(dir);
}
// Write the configuration file
fs.writeFile(path.resolve(dir,me.id+'.xml'),me._xml,function(){
fs.writeFile(path.resolve(dir, me.id + '.xml'), me._xml, function () {
// Write the exe file
winsw.createExe(me.id,dir,function(){
me.execute('"'+path.resolve(dir,me._exe)+'" install',function(){
winsw.createExe(me.id, dir, function () {
me.execute('"' + path.resolve(dir, me._exe) + '" install', function () {
sleep(2);

@@ -602,7 +601,7 @@ me.emit('install');

writable: false,
value: function(waitTime){
value: function (waitTime) {
var me = this;
waitTime = waitTime || 2; // The same wait time as in the install method
if (!this.exists){
if (!this.exists) {
console.log('Uninstall was skipped because process does not exist or could not be found.');

@@ -613,15 +612,15 @@ this.emit('alreadyuninstalled');

var uninstaller = function(){
var uninstaller = function () {
// Uninstall the process
me.execute('"'+path.resolve(me.root,me._exe)+'" uninstall',function(error,stdout,stderr){
if (error){
me.execute('"' + path.resolve(me.root, me._exe) + '" uninstall', function (error, stdout, stderr) {
if (error) {
me.checkPermError(error);
} else if (stderr.trim().length > 0){
console.log('Error: ',stderr);
} else if (stderr.trim().length > 0) {
console.log('Error: ', stderr);
} else {
sleep(waitTime); // Wait for uninstall to fully finish
var rm = function(file){
if (fs.existsSync(path.join(me.root,file))){
fs.unlinkSync(path.join(me.root,file));
var rm = function (file) {
if (fs.existsSync(path.join(me.root, file))) {
fs.unlinkSync(path.join(me.root, file));
}

@@ -631,12 +630,12 @@ };

// Remove the daemon files individually to prevent security warnings.
rm(me.id+'.xml');
rm(me.id + '.xml');
// Remove known wrappers
rm(me.id+'.wrapper.log');
rm(me.id+'.out.log');
rm(me.id+'.err.log');
rm(me.id + '.wrapper.log');
rm(me.id + '.out.log');
rm(me.id + '.err.log');
// Remove the executable and executable .NET runtime config file
rm(me.id+'.exe');
rm(me.id+'.exe.config');
rm(me.id + '.exe');
rm(me.id + '.exe.config');

@@ -648,3 +647,3 @@ // Remove all other files

})
_other_files.forEach(function(f){
_other_files.forEach(function (f) {
rm(f)

@@ -655,4 +654,4 @@ });

if (fs.readdirSync(me.root).length === 0) {
if (me.root !== path.dirname(me.script)){
fs.rmdir(me.root,function(){
if (me.root !== path.dirname(me.script)) {
fs.rmdir(me.root, function () {
sleep(1);

@@ -672,4 +671,4 @@ me.emit('uninstall');

this.once('stop',uninstaller);
this.once('alreadystopped',uninstaller);
this.once('stop', uninstaller);
this.once('alreadystopped', uninstaller);
this.stop();

@@ -691,24 +690,24 @@ }

configurable: false,
value: function(){
value: function () {
var me = this;
if (this.name == null){
if (this.name == null) {
throw "A name for the service is required.";
}
if (!this.exists){
throw Error('The service "'+this.name+'" does not exist or could not be found.');
if (!this.exists) {
throw Error('The service "' + this.name + '" does not exist or could not be found.');
}
this.execute('NET START "'+me._exe+'"',function(err,stdout,stderr){
if (err){
if (err.code == 2){
if (err.message.indexOf('already been started') >= 0 && err.message.indexOf('service name is invalid') < 0){
this.execute('NET START "' + me._exe + '"', function (err, stdout, stderr) {
if (err) {
if (err.code == 2) {
if (err.message.indexOf('already been started') >= 0 && err.message.indexOf('service name is invalid') < 0) {
me.log.warn('An attempt to start the service failed because the service is already running. The process should be stopped before starting, or the restart method should be used.');
me.emit('error',err);
me.emit('error', err);
return;
} else if (err.message.indexOf('service name is invalid') < 0){
} else if (err.message.indexOf('service name is invalid') < 0) {
me.checkPermError(err);
console.log(err);
me.emit('error',err);
me.emit('error', err);
return;

@@ -737,8 +736,8 @@ }

writable: false,
value: function(){
value: function () {
var me = this;
me.execute('NET STOP "'+me._exe+'"',function(err,stdout,stderr){
if (err){
if (err.code == 2){
me.execute('NET STOP "' + me._exe + '"', function (err, stdout, stderr) {
if (err) {
if (err.code == 2) {
me.log.warn('An attempt to stop the service failed because the service is/was not running.');

@@ -765,5 +764,5 @@ me.emit('alreadystopped');

writable: false,
value: function(callback){
value: function (callback) {
var me = this;
this.once('stop',me.start);
this.once('stop', me.start);
this.stop();

@@ -779,7 +778,7 @@ }

enumerable: true,
get: function(){
if (this.script == null || this.name == null){
get: function () {
if (this.script == null || this.name == null) {
throw Error('Script and name are required but were not specified.');
}
return fs.existsSync(path.join(this.directory(),this.id+'.exe')) && fs.existsSync(path.join(this.directory(),this.id+'.xml')) ;
return fs.existsSync(path.join(this.directory(), this.id + '.exe')) && fs.existsSync(path.join(this.directory(), this.id + '.xml'));
}

@@ -793,22 +792,22 @@ },

configurable: false,
value: function(cmd,options,callback) {
value: function (cmd, options, callback) {
var me = this;
callback = callback || function(){};
callback = callback || function () { };
options = options || {};
wincmd.isAdminUser(function(isAdmin){
wincmd.isAdminUser(function (isAdmin) {
if (isAdmin) {
if (typeof options === 'function'){
if (typeof options === 'function') {
callback = options;
options = {};
}
if (me.user.account !== null && me.user.password !== null){
_cmd = "runas /profile /user:"+me.user.domain+"\\"+me.user.account+" "+cmd;
exec(cmd,options,callback);
} else if (me.sudo.password !== null){
if (me.user.account !== null && me.user.password !== null) {
_cmd = "runas /profile /user:" + me.user.domain + "\\" + me.user.account + " " + cmd;
exec(cmd, options, callback);
} else if (me.sudo.password !== null) {
// If the user is not an admin, but a sudo password is provided for admin,
// attempt to launch using sudo.
wincmd.sudo(cmd,me.sudo.password||'',options,callback);
wincmd.sudo(cmd, me.sudo.password || '', options, callback);
} else {
wincmd.elevate(cmd,options,callback)
wincmd.elevate(cmd, options, callback)
}

@@ -828,7 +827,7 @@ } else {

configurable: false,
value: function(error){
if (error.message.indexOf('Administrator access') >= 0 || error.message.indexOf('Access is denied') >= 0){
try {this.log.error(PermError);} catch(e){console.log(PermError);}
value: function (error) {
if (error.message.indexOf('Administrator access') >= 0 || error.message.indexOf('Access is denied') >= 0) {
try { this.log.error(PermError); } catch (e) { console.log(PermError); }
} else {
try {this.log.error(error.toString());} catch(e) {console.log(error.toString());}
try { this.log.error(error.toString()); } catch (e) { console.log(error.toString()); }
}

@@ -842,8 +841,8 @@ process.exit(1);

var util = require('util'),
EventEmitter = require('events').EventEmitter;
EventEmitter = require('events').EventEmitter;
// Inherit Events
util.inherits(daemon,EventEmitter);
util.inherits(daemon, EventEmitter);
// Export functionality for the module.
module.exports = daemon;
module.exports = daemon;

@@ -45,13 +45,13 @@ /**

var wincmd = require('./binaries'),
exec = require("child_process").exec,
eventlogs = ['APPLICATION','SYSTEM'],
validtypes = ['ERROR','WARNING','INFORMATION','SUCCESSAUDIT','FAILUREAUDIT'];
exec = require("child_process").exec,
eventlogs = ['APPLICATION', 'SYSTEM'],
validtypes = ['ERROR', 'WARNING', 'INFORMATION', 'SUCCESSAUDIT', 'FAILUREAUDIT'];
// Write a message to the log. This will create the log if it doesn't exist.
var write = function(log,src,type,msg,id,callback){
var write = function (log, src, type, msg, id, callback) {
var cmd;
if (msg == null) {return};
if (msg.trim().length == 0) {return};
if (msg == null) { return };
if (msg.trim().length == 0) { return };
msg = msg.replace(/\r\n|\n\r|\r|\n/g, "\f")

@@ -66,8 +66,8 @@

cmd = "eventcreate /L "+log+" /T "+type+" /SO \""+src+"\" /D \""+msg+"\" /ID "+id;
cmd = "eventcreate /L " + log + " /T " + type + " /SO \"" + src + "\" /D \"" + msg + "\" /ID " + id;
exec(cmd, function(err) {
exec(cmd, function (err) {
if (err && err.message.indexOf("Access is Denied")) {
wincmd.elevate(cmd, callback);
} else if (callback){
} else if (callback) {
callback(err);

@@ -79,3 +79,3 @@ }

// Basic functionality
var logger = function(config){
var logger = function (config) {

@@ -91,3 +91,3 @@ config = config || {};

// Common attributes
Object.defineProperties(this,{
Object.defineProperties(this, {

@@ -119,7 +119,7 @@ /**

enumerable: true,
get: function(){
get: function () {
return this._logname.toUpperCase();
},
set: function(value) {
if (value){
set: function (value) {
if (value) {
this._logname = eventlogs.indexOf(value.toUpperCase()) >= 0 ? value.toUpperCase() : 'APPLICATION';

@@ -144,4 +144,4 @@ }

configurable: false,
value: function(message,code,callback) {
write(this.eventLog,this.source,'INFORMATION',message,code,callback);
value: function (message, code, callback) {
write(this.eventLog, this.source, 'INFORMATION', message, code, callback);
}

@@ -152,3 +152,3 @@ },

enumerable: false,
get: function(){
get: function () {
return this.info;

@@ -172,4 +172,4 @@ }

configurable: false,
value: function(message,code,callback) {
write(this.eventLog,this.source,'ERROR',message,code,callback);
value: function (message, code, callback) {
write(this.eventLog, this.source, 'ERROR', message, code, callback);
}

@@ -192,4 +192,4 @@ },

configurable: false,
value: function(message,code,callback) {
write(this.eventLog,this.source,'WARNING',message,code,callback);
value: function (message, code, callback) {
write(this.eventLog, this.source, 'WARNING', message, code, callback);
}

@@ -200,3 +200,3 @@ },

enumerable: false,
get: function(){return this.warn;}
get: function () { return this.warn; }
},

@@ -218,4 +218,4 @@

configurable: false,
value: function(message,code,callback) {
write(this.eventLog,this.source,'SUCCESSAUDIT',message,code,callback);
value: function (message, code, callback) {
write(this.eventLog, this.source, 'SUCCESSAUDIT', message, code, callback);
}

@@ -238,4 +238,4 @@ },

configurable: false,
value: function(message,code,callback) {
write(this.eventLog,this.source,'FAILUREAUDIT',message,code,callback);
value: function (message, code, callback) {
write(this.eventLog, this.source, 'FAILUREAUDIT', message, code, callback);
}

@@ -246,2 +246,2 @@ }

module.exports = logger;
module.exports = logger;

@@ -18,3 +18,3 @@ /**

*/
if (require('os').platform().indexOf('win32') < 0){
if (require('os').platform().indexOf('win32') < 0) {
throw 'node-windows is only supported on Windows.';

@@ -28,3 +28,3 @@ }

var commands = require('./cmd');
for (var item in commands){
for (var item in commands) {
module.exports[item] = commands[item];

@@ -35,2 +35,2 @@ }

module.exports.Service = require('./daemon');
module.exports.EventLogger = require('./eventlog');
module.exports.EventLogger = require('./eventlog');

@@ -77,2 +77,3 @@ module.exports = {

xml.push({argument:config.script.trim()});
console.log({loc: 'winsw.js ~line 77', xml, config})
multi('argument',config.wrapperArgs,' ');

@@ -105,3 +106,3 @@

}
// Optionally set the stoptimeout

@@ -108,0 +109,0 @@ if (config.stoptimeout) {

@@ -0,120 +1,91 @@

const { errorMonitor } = require('events');
// Handle input parameters
var Logger = require('./eventlog'),
Args = require('@author.io/args'),
net = require('net'),
max = 60,
p = require('path'),
fork = require('child_process').fork,
attempts = 0,
startTime = null,
starts = 0,
child = null,
forcekill = false;
optimist = require('yargs'),
net = require('net'),
max = 60,
p = require('path'),
fs = require('fs'),
argv = optimist
.demand('file')
.alias('f', 'file')
.describe('file', 'The absolute path of the script to be run as a process.')
.check(function (argv) {
var exists = fs.existsSync(p.resolve(argv.f))
if (!exists) {
throw new Error(argv.f + ' does not exist or cannot be found.')
}
return true
})
.describe('scriptoptions', 'The options to be sent to the script.')
.alias('d', 'cwd')
.describe('cwd', 'The absolute path of the current working directory of the script to be run as a process.')
// .check(function(argv){
// require('fs').existsSync(p.resolve(argv.d),function(exists){
// return exists;
// });
// })
.demand('log')
.alias('l', 'log')
.describe('log', 'The descriptive name of the log for the process')
.default('eventlog', 'APPLICATION')
.alias('e', 'eventlog')
.describe('eventlog', 'The event log container. This must be APPLICATION or SYSTEM.')
.default('maxretries', -1)
.alias('m', 'maxretries')
.describe('maxretries', 'The maximim number of times the process will be auto-restarted.')
.default('maxrestarts', 5)
.alias('r', 'maxrestarts')
.describe('maxrestarts', 'The maximim number of times the process should be restarted within a ' + max + ' second period shutting down.')
.default('wait', 1)
.alias('w', 'wait')
.describe('wait', 'The number of seconds between each restart attempt.')
// .check(function (argv) {
// return argv.w >= 0;
// })
.default('grow', .25)
.alias('g', 'grow')
.describe('grow', 'A percentage growth rate at which the wait time is increased.')
// .check(function (argv) {
// return (argv.g >= 0 && argv.g <= 1);
// })
.default('abortonerror', 'no')
.alias('a', 'abortonerror')
.describe('abortonerror', 'Do not attempt to restart the process if it fails with an error,')
.check(function (argv) {
return ['y', 'n', 'yes', 'no'].indexOf(argv.a.trim().toLowerCase()) >= 0;
})
.default('stopparentfirst', 'no')
.alias('s', 'stopparentfirst')
.describe('stopparentfirst', 'Allow the script to exit using a shutdown message.')
.check(function (argv) {
return ['y', 'n', 'yes', 'no'].indexOf(argv.a.trim().toLowerCase()) >= 0;
})
.parse(),
log = new Logger(argv.e == undefined ? argv.l : { source: argv.l, eventlog: argv.e }),
fork = require('child_process').fork,
script = p.resolve(argv.f),
wait = argv.w * 1000,
grow = argv.g + 1,
attempts = 0,
startTime = null,
starts = 0,
child = null
forcekill = false;
Args.configure({
file: {
type: 'string',
required: true,
alias: 'f',
description: 'The absolute path of the script to be run as a process.',
validate: function(value){
require('fs').existsSync(p.resolve(value),function(exists){
return exists;
});
}
},
scriptoptions: {
type: 'string',
description: 'The options to be sent to the script.'
},
cwd: {
type: 'string',
description: 'The absolute path of the current working directory of the script to be run as a process.',
alias: 'd',
validate: function(value){
require('fs').existsSync(p.resolve(value),function(exists){
return exists;
});
}
},
log: {
type: 'string',
required: true,
alias: 'l',
description: 'The descriptive name of the log for the process'
},
eventlog: {
type: 'string',
alias: 'e',
description: 'The event log container. This must be APPLICATION or SYSTEM.',
defaults: 'APPLICATION'
},
maxretries: {
type: 'number',
alias: 'm',
description: 'The maximim number of times the process will be auto-restarted.',
defaults: -1
},
maxrestarts: {
type: 'number',
alias: 'r',
description: 'The maximim number of times the process should be restarted within a '+max+' second period shutting down.',
defaults: 5
},
wait: {
type: 'number',
alias: 'w',
description: 'The number of seconds between each restart attempt.',
defaults: 1,
validate: function(value){
return value >= 0;
}
},
grow: {
type: 'number',
alias: 'g',
description: 'A percentage growth rate at which the wait time is increased.',
defaults: .25,
validate: function(value){
return value >= 0 && value <= 1;
}
},
abortonerror: {
type: 'string',
alias: 'a',
description: 'Do not attempt to restart the process if it fails with an error.',
defaults: 'no',
options: ['y','n','yes','no']
},
stopparentfirst: {
type: 'string',
alias: 's',
decribe: 'Allow the script to exit using a shutdown message.',
defaults: 'no',
options: ['y','n','yes','no']
}
});
Args.disallowUnrecognized();
Args.enforceRules();
var argv = Args.data,
log = new Logger(argv.eventlog == undefined ? argv.log : {source:argv.log,eventlog:argv.eventlog}),
script = p.resolve(argv.file),
wait = argv.wait*1000,
grow = argv.grow+1;
if (argv.cwd){
if (!require('fs').existsSync(p.resolve(argv.cwd))){
console.warn(argv.cwd+' not found.');
argv.cwd = process.cwd();
if (argv.d) {
if (!require('fs').existsSync(p.resolve(argv.d))) {
console.warn(argv.d + ' not found.');
argv.d = process.cwd();
}
argv.cwd = p.resolve(argv.cwd);
argv.d = p.resolve(argv.d);
}
if (typeof argv.maxretries === 'string'){
argv.maxretries = parseInt(argv.maxretries);
if (typeof argv.m === 'string') {
argv.m = parseInt(argv.m);
}
// Set the absolute path of the file
argv.file = p.resolve(argv.file);
argv.f = p.resolve(argv.f);

@@ -125,4 +96,4 @@ // Hack to force the wrapper process to stay open by launching a ghost socket server

server.on('error', function (err) {
launch('warn', err.message);
server = net.createServer().listen();
launch('warn', err.message);
server = net.createServer().listen();
});

@@ -134,9 +105,9 @@

*/
var monitor = function() {
if(!child || !child.pid) {
var monitor = function () {
if (!child || !child.pid) {
// If the number of periodic starts exceeds the max, kill the process
if (starts >= argv.maxrestarts){
if (new Date().getTime()-(max*1000) <= startTime.getTime()){
log.error('Too many restarts within the last '+max+' seconds. Please check the script.');
if (starts >= argv.r) {
if (new Date().getTime() - (max * 1000) <= startTime.getTime()) {
log.error('Too many restarts within the last ' + max + ' seconds. Please check the script.');
process.exit();

@@ -146,7 +117,7 @@ }

setTimeout(function(){
setTimeout(function () {
wait = wait * grow;
attempts += 1;
if (attempts > argv.maxretries && argv.maxretries >= 0){
log.error('Too many restarts. '+argv.file+' will not be restarted because the maximum number of total restarts has been exceeded.');
if (attempts > argv.m && argv.m >= 0) {
log.error('Too many restarts. ' + argv.f + ' will not be restarted because the maximum number of total restarts has been exceeded.');
process.exit();

@@ -156,7 +127,7 @@ } else {

}
},wait);
}, wait);
} else {
// reset attempts and wait time
attempts = 0;
wait = argv.wait * 1000;
wait = argv.w * 1000;
}

@@ -172,4 +143,3 @@ };

*/
var launch = function(logLevel, msg) {
var launch = function (logLevel, msg) {
if (forcekill) {

@@ -180,3 +150,3 @@ log.info("Process killed");

//log.info('Starting '+argv.file);
//log.info('Starting '+argv.f);
if (logLevel && msg) {

@@ -189,6 +159,6 @@ log[logLevel](msg);

startTime = startTime || new Date();
setTimeout(function(){
setTimeout(function () {
startTime = null;
starts = 0;
},(max*1000)+1);
}, (max * 1000) + 1);
}

@@ -198,16 +168,16 @@ starts += 1;

// Fork the child process
var opts = {env:process.env};
var opts = { env: process.env };
var args = [];
if (argv.cwd) opts.cwd = argv.cwd;
if (argv.stopparentfirst) opts.detached = true;
if (argv.d) opts.cwd = argv.d;
if (argv.s) opts.detached = true;
if (argv.scriptoptions) args = argv.scriptoptions.split(' ');
child = fork(script,args,opts);
child = fork(script, args, opts);
// When the child dies, attempt to restart based on configuration
child.on('exit',function(code){
log.warn(argv.file+' stopped running.');
child.on('exit', function (code) {
log.warn(argv.f + ' stopped running.');
// If an error is thrown and the process is configured to exit, then kill the parent.
if (code !== 0 && argv.abortonerror == "yes"){
log.error(argv.file+' exited with error code '+code);
if (code !== 0 && argv.a == "yes") {
log.error(argv.f + ' exited with error code ' + code);
process.exit();

@@ -225,6 +195,6 @@ //server.unref();

var killkid = function(){
var killkid = function () {
forcekill = true;
if (child) {
if (argv.stopparentfirst) {
if (argv.s) {
child.send('shutdown');

@@ -235,3 +205,3 @@ } else {

} else {
log.warn('Attempted to kill an unrecognized process.');
log.warn('Attempted to kill an unrecognized process.')
}

@@ -244,7 +214,7 @@ }

process.on('uncaughtException', function(err) {
launch('warn', err.message);
process.on('uncaughtException', function (err) {
launch('warn', err.message);
});
// Launch the process
launch('info', 'Starting ' + argv.file);
launch('info', 'Starting ' + argv.f);
{
"name": "node-windows",
"version": "1.0.0-beta.7",
"version": "1.0.0-beta.8",
"description": "Support for Windows services, event logging, UAC, and several helper methods for interacting with the OS.",

@@ -21,4 +21,4 @@ "keywords": [

"dependencies": {
"@author.io/arg": "1.3.22",
"xml": "1.0.1"
"xml": "1.0.1",
"yargs": "^17.5.1"
},

@@ -25,0 +25,0 @@ "readmeFilename": "README.md",

# node-windows
![NPM version](https://img.shields.io/npm/v/node-windows?label=node-windows&logo=npm&style=for-the-badge)
![NGN Dependencies](https://david-dm.org/coreybutler/node-windows.svg?style=for-the-badge)
![NGN Dependencies](https://img.shields.io/librariesio/release/npm/node-windows?style=for-the-badge)

@@ -6,0 +6,0 @@ [Tweet me (@goldglovecb)](http://twitter.com/goldglovecb) if you need me.

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc