UNPKG

windows-shortcuts

Version:

Create, edit, and query Windows shortcuts (.lnk files)

139 lines (126 loc) 4.63 kB
var execFile = require('child_process').execFile; var pathUtils = require('path'); /* * options object (also passed by query()) * target : The path the shortcut points to * args : The arguments passed to the target as a string * workingDir : The working directory of the target * runStyle : State to open the window in: ws.NORMAL (1), ws.MAX (3), or ws.MIN (7) * icon : The path to the shortcut icon file * iconIndex : An optional index for the image in the icon file * hotkey : A numerical hotkey * desc : A description */ function parseQuery(stdout) { // Parses the stdout of a shortcut.exe query into a JS object var result = {}; result.expanded = {}; stdout.split(/[\r\n]+/) .filter(function(line) { return line.indexOf('=') !== -1; }) .forEach(function(line) { var pair = line.split('=', 2), key = pair[0], value = pair[1]; if (key === "TargetPath") result.target = value; else if (key === "TargetPathExpanded") result.expanded.target = value; else if (key === "Arguments") result.args = value; else if (key === "ArgumentsExpanded") result.expanded.args = value; else if (key === "WorkingDirectory") result.workingDir = value; else if (key === "WorkingDirectoryExpanded") result.expanded.workingDir = value; else if (key === "RunStyle") result.runStyle = +value; else if (key === "IconLocation") { result.icon = value.split(',')[0]; result.iconIndex = value.split(',')[1]; } else if (key === "IconLocationExpanded") { result.expanded.icon = value.split(',')[0]; } else if (key === "HotKey") result.hotkey = +value.match(/\d+/)[0]; else if (key === "Description") result.desc = value; }); Object.keys(result.expanded).forEach(function(key) { result.expanded[key] = result.expanded[key] || result[key]; }); return result; } // This function is supposed to act like a windows shell for compatibility with v0.1.2 // Meaning, treat carets as escape characters (replace ^<any> with <any>) and expand env vars function expandEnv(path) { var envRE = /(^|[^^])%((?:\^.|[^^%])*)%/g; // Matches env vars, accounting for escaped chars. I feel dirty. return path.replace(envRE, function(_, g1, g2) { return g1 + process.env[g2]; }).replace(/\^(.)/g,"$1"); } function commandArgs(type, path, options) { // Generates a command for shortcut.exe var args = ['/A:' + type, '/F:' + expandEnv(path)]; if (options) { if (options.target) args.push('/T:' + expandEnv(options.target)); if (options.args) args.push('/P:' + expandEnv(options.args)); if (options.workingDir) args.push('/W:' + expandEnv(options.workingDir) + ''); if (options.runStyle) args.push('/R:' + options.runStyle); if (options.icon) { args.push('/I:' + expandEnv(options.icon) + ('iconIndex' in options ? ',' + options.iconIndex : '')); } if (options.hotkey) args.push('/H:' + options.hotkey); if (options.desc) args.push('/D:' + expandEnv(options.desc) + ''); } return args; } function isString(x) { return Object.prototype.toString.call(x) === "[object String]"; } exports.query = function(path, callback) { execFile(__dirname + '/shortcut/Shortcut.exe', ['/A:Q', '/F:' + expandEnv(path)], function(error, stdout, stderr) { var result = parseQuery(stdout); callback(error ? stderr || stdout : null, result); }); }; exports.create = function(path, optionsOrCallbackOrTarget, callback) { var options = isString(optionsOrCallbackOrTarget) ? {target : optionsOrCallbackOrTarget} : optionsOrCallbackOrTarget; callback = typeof optionsOrCallbackOrTarget === 'function' ? optionsOrCallbackOrTarget : callback; if (pathUtils.extname(path) !== ".lnk") { // Automatically generate shortcut if a .lnk file name is not given if (options && options.target) { var targetObj = pathUtils.parse(options.target); // TODO: deal with parse failure? var basename = targetObj.ext === ".lnk" ? options.target : targetObj.name + ".lnk"; path = pathUtils.join(path, basename); } else { path = pathUtils.join(path, "New Shortcut.lnk"); } } execFile(__dirname + '\\shortcut\\Shortcut.exe', commandArgs('C', path, options), function(error, stdout, stderr) { if (callback) callback(error ? stderr || stdout : null); }); }; exports.edit = function(path, options, callback) { execFile(__dirname + '/shortcut/Shortcut.exe', commandArgs('E', path, options), function(error, stdout, stderr) { if (callback) callback(error ? stderr || stdout : null); }); }; // Shortcut open states exports.NORMAL = 1; exports.MAX = 3; exports.MIN = 7;