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
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 36 additions & 36 deletions lib/utils.js
Original file line number Diff line number Diff line change
@@ -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;
};

@@ -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
@@ -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, {});

@@ -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.'));
}
@@ -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
@@ -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;
@@ -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;
@@ -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;
@@ -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);

@@ -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);
@@ -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);

@@ -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;

@@ -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
@@ -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 || {};

@@ -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(','));
}
@@ -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) {
@@ -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);

@@ -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);

@@ -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')
@@ -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);
});
});
20 changes: 14 additions & 6 deletions notifiers/toaster.js
Original file line number Diff line number Diff line change
@@ -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 };
@@ -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
)
);

@@ -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, {
@@ -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;
}