Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix hang on Disabled Windows 10 Notifications #335

Merged
merged 2 commits into from Jul 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
72 changes: 36 additions & 36 deletions lib/utils.js
Expand Up @@ -16,15 +16,15 @@ function clone(obj) {

module.exports.clone = clone;

var escapeQuotes = function(str) {
var escapeQuotes = function (str) {
if (typeof str === 'string') {
return str.replace(/(["$`\\])/g, '\\$1');
} else {
return str;
}
};

var inArray = function(arr, val) {
var inArray = function (arr, val) {
return arr.indexOf(val) !== -1;
};

Expand All @@ -48,15 +48,15 @@ var notifySendFlags = {
'app-name': 'app-name'
};

module.exports.command = function(notifier, options, cb) {
module.exports.command = function (notifier, options, cb) {
notifier = shellwords.escape(notifier);
if (process.env.DEBUG && process.env.DEBUG.indexOf('notifier') !== -1) {
console.info('node-notifier debug info (command):');
console.info('[notifier path]', notifier);
console.info('[notifier options]', options.join(' '));
}

return cp.exec(notifier + ' ' + options.join(' '), function(
return cp.exec(notifier + ' ' + options.join(' '), function (
error,
stdout,
stderr
Expand All @@ -66,26 +66,26 @@ module.exports.command = function(notifier, options, cb) {
});
};

module.exports.fileCommand = function(notifier, options, cb) {
module.exports.fileCommand = function (notifier, options, cb) {
if (process.env.DEBUG && process.env.DEBUG.indexOf('notifier') !== -1) {
console.info('node-notifier debug info (fileCommand):');
console.info('[notifier path]', notifier);
console.info('[notifier options]', options.join(' '));
}

return cp.execFile(notifier, options, function(error, stdout, stderr) {
return cp.execFile(notifier, options, function (error, stdout, stderr) {
if (error) return cb(error, stdout);
cb(stderr, stdout);
});
};

module.exports.fileCommandJson = function(notifier, options, cb) {
module.exports.fileCommandJson = function (notifier, options, cb) {
if (process.env.DEBUG && process.env.DEBUG.indexOf('notifier') !== -1) {
console.info('node-notifier debug info (fileCommandJson):');
console.info('[notifier path]', notifier);
console.info('[notifier options]', options.join(' '));
}
return cp.execFile(notifier, options, function(error, stdout, stderr) {
return cp.execFile(notifier, options, function (error, stdout, stderr) {
if (error) return cb(error, stdout);
if (!stdout) return cb(error, {});

Expand All @@ -98,13 +98,13 @@ module.exports.fileCommandJson = function(notifier, options, cb) {
});
};

module.exports.immediateFileCommand = function(notifier, options, cb) {
module.exports.immediateFileCommand = function (notifier, options, cb) {
if (process.env.DEBUG && process.env.DEBUG.indexOf('notifier') !== -1) {
console.info('node-notifier debug info (notifier):');
console.info('[notifier path]', notifier);
}

notifierExists(notifier, function(_, exists) {
notifierExists(notifier, function (_, exists) {
if (!exists) {
return cb(new Error('Notifier (' + notifier + ') not found on system.'));
}
Expand All @@ -114,7 +114,7 @@ module.exports.immediateFileCommand = function(notifier, options, cb) {
};

function notifierExists(notifier, cb) {
return fs.stat(notifier, function(err, stat) {
return fs.stat(notifier, function (err, stat) {
if (!err) return cb(err, stat.isFile());

// Check if Windows alias
Expand All @@ -124,14 +124,14 @@ function notifierExists(notifier, cb) {
}

// Check if there is an exe file in the directory
return fs.stat(notifier + '.exe', function(err, stat) {
return fs.stat(notifier + '.exe', function (err, stat) {
if (err) return cb(err, false);
cb(err, stat.isFile());
});
});
}

var mapAppIcon = function(options) {
var mapAppIcon = function (options) {
if (options.appIcon) {
options.icon = options.appIcon;
delete options.appIcon;
Expand All @@ -140,7 +140,7 @@ var mapAppIcon = function(options) {
return options;
};

var mapText = function(options) {
var mapText = function (options) {
if (options.text) {
options.message = options.text;
delete options.text;
Expand All @@ -149,7 +149,7 @@ var mapText = function(options) {
return options;
};

var mapIconShorthand = function(options) {
var mapIconShorthand = function (options) {
if (options.i) {
options.icon = options.i;
delete options.i;
Expand All @@ -158,7 +158,7 @@ var mapIconShorthand = function(options) {
return options;
};

module.exports.mapToNotifySend = function(options) {
module.exports.mapToNotifySend = function (options) {
options = mapAppIcon(options);
options = mapText(options);

Expand All @@ -173,7 +173,7 @@ module.exports.mapToNotifySend = function(options) {
return options;
};

module.exports.mapToGrowl = function(options) {
module.exports.mapToGrowl = function (options) {
options = mapAppIcon(options);
options = mapIconShorthand(options);
options = mapText(options);
Expand All @@ -187,7 +187,7 @@ module.exports.mapToGrowl = function(options) {
return options;
};

module.exports.mapToMac = function(options) {
module.exports.mapToMac = function (options) {
options = mapIconShorthand(options);
options = mapText(options);

Expand Down Expand Up @@ -233,7 +233,7 @@ function isArray(arr) {
module.exports.isArray = isArray;

function noop() {}
module.exports.actionJackerDecorator = function(emitter, options, fn, mapper) {
module.exports.actionJackerDecorator = function (emitter, options, fn, mapper) {
options = clone(options);
fn = fn || noop;

Expand All @@ -244,7 +244,7 @@ module.exports.actionJackerDecorator = function(emitter, options, fn, mapper) {
);
}

return function(err, data) {
return function (err, data) {
var resultantData = data;
var metadata = {};
// Allow for extra data if resultantData is an object
Expand Down Expand Up @@ -273,7 +273,7 @@ module.exports.actionJackerDecorator = function(emitter, options, fn, mapper) {
};
};

module.exports.constructArgumentList = function(options, extra) {
module.exports.constructArgumentList = function (options, extra) {
var args = [];
extra = extra || {};

Expand All @@ -287,7 +287,7 @@ module.exports.constructArgumentList = function(options, extra) {
var keepNewlines = !!extra.keepNewlines;
var wrapper = extra.wrapper === undefined ? '"' : extra.wrapper;

var escapeFn = function(arg) {
var escapeFn = function (arg) {
if (isArray(arg)) {
return removeNewLines(arg.join(','));
}
Expand All @@ -301,7 +301,7 @@ module.exports.constructArgumentList = function(options, extra) {
return wrapper + arg + wrapper;
};

initial.forEach(function(val) {
initial.forEach(function (val) {
args.push(escapeFn(val));
});
for (var key in options) {
Expand Down Expand Up @@ -356,7 +356,7 @@ var allowedToasterFlags = [
];
var toasterSoundPrefix = 'Notification.';
var toasterDefaultSound = 'Notification.Default';
module.exports.mapToWin8 = function(options) {
module.exports.mapToWin8 = function (options) {
options = mapAppIcon(options);
options = mapText(options);

Expand Down Expand Up @@ -439,7 +439,7 @@ module.exports.mapToWin8 = function(options) {
return options;
};

module.exports.mapToNotifu = function(options) {
module.exports.mapToNotifu = function (options) {
options = mapAppIcon(options);
options = mapText(options);

Expand Down Expand Up @@ -492,29 +492,29 @@ module.exports.mapToNotifu = function(options) {
return options;
};

module.exports.isMac = function() {
module.exports.isMac = function () {
return os.type() === 'Darwin';
};

module.exports.isMountainLion = function() {
module.exports.isMountainLion = function () {
return (
os.type() === 'Darwin' &&
semver.satisfies(garanteeSemverFormat(os.release()), '>=12.0.0')
);
};

module.exports.isWin8 = function() {
module.exports.isWin8 = function () {
return (
os.type() === 'Windows_NT' &&
semver.satisfies(garanteeSemverFormat(os.release()), '>=6.2.9200')
);
};

module.exports.isWSL = function() {
module.exports.isWSL = function () {
return isWSL;
};

module.exports.isLessThanWin8 = function() {
module.exports.isLessThanWin8 = function () {
return (
os.type() === 'Windows_NT' &&
semver.satisfies(garanteeSemverFormat(os.release()), '<6.2.9200')
Expand All @@ -538,19 +538,19 @@ function sanitizeNotifuTypeArgument(type) {
return 'info';
}

module.exports.createNamedPipe = namedPipe => {
module.exports.createNamedPipe = (server) => {
const buf = Buffer.alloc(BUFFER_SIZE);

return new Promise(resolve => {
const server = net.createServer(stream => {
stream.on('data', c => {
return new Promise((resolve) => {
server.instance = net.createServer((stream) => {
stream.on('data', (c) => {
buf.write(c.toString());
});
stream.on('end', () => {
server.close();
server.instance.close();
});
});
server.listen(namedPipe, () => {
server.instance.listen(server.namedPipe, () => {
resolve(buf);
});
});
Expand Down
20 changes: 14 additions & 6 deletions notifiers/toaster.js
Expand Up @@ -54,7 +54,9 @@ function notifyRaw(options, callback) {
callback = callback || noop;
var is64Bit = os.arch() === 'x64';
var resultBuffer;
const namedPipe = getPipeName();
const server = {
namedPipe: getPipeName()
};

if (typeof options === 'string') {
options = { title: 'node-notifier', message: options };
Expand Down Expand Up @@ -94,16 +96,22 @@ function notifyRaw(options, callback) {
callback(err, result);
}
callback(null, result);

// https://github.com/mikaelbr/node-notifier/issues/334
// Due to an issue with snoretoast not using stdio and pipe
// when notifications are disabled, make sure named pipe server
// is closed before exiting.
server.instance && server.instance.close();
};

var actionJackedCallback = err =>
var actionJackedCallback = (err) =>
snoreToastResultParser(
err,
utils.actionJackerDecorator(
this,
options,
callback,
data => data || false
(data) => data || false
)
);

Expand All @@ -122,9 +130,9 @@ function notifyRaw(options, callback) {
}

// Add pipeName option, to get the output
utils.createNamedPipe(namedPipe).then(out => {
utils.createNamedPipe(server).then((out) => {
resultBuffer = out;
options.pipeName = namedPipe;
options.pipeName = server.namedPipe;

options = utils.mapToWin8(options);
var argsList = utils.constructArgumentList(options, {
Expand All @@ -145,7 +153,7 @@ function notifyRaw(options, callback) {
}

Object.defineProperty(WindowsToaster.prototype, 'notify', {
get: function() {
get: function () {
if (!this._notify) this._notify = notifyRaw.bind(this);
return this._notify;
}
Expand Down