windows
Version:
A collection of utilities for Windows for Node.js
140 lines (112 loc) • 3.57 kB
JavaScript
var path = require('path');
var fs = require('fs');
var child_process = require('child_process');
var props = module.exports.properties =
[ 'target', 'cwd', 'style', 'args',
'icon', 'description', 'hotkey' ];
var styles = module.exports.styles =
[ 'Hidden', 'Normal', 'Minimized', 'Maximized',
'Normal unfocused', 'Minimized unfocused' ];
var special = module.exports.specialFolders =
[ 'AllUsersDesktop', 'AllUsersStartMenu', 'AllUsersPrograms', 'AllUsersStartup',
'Desktop', 'Favorites', 'Fonts', 'MyDocuments', 'NetHood', 'PrintHood',
'Programs', 'Recent','SendTo', 'StartMenu', 'Startup', 'Templates' ];
module.exports.createShortcut = function createShortcut(options){ return new Shortcut(options) }
function Shortcut(options){
Object.keys(options).forEach(function(k){
this[k] = options[k];
}, this);
}
Shortcut.prototype = {
location: '',
target: '',
startIn: process.cwd(),
style: 'Normal',
create: function(callback){
var script = './' + Date.now() + '.js';
fs.writeFileSync(script, this.toString());
child_process.exec('cscript //NoLogo ' + script, function(err, out){
fs.unlink(script);
callback(err, out);
});
},
toString: function(){
var properties = props.map(function(p){
if (typeof this[p] === 'undefined') return '';
return 's.'+propMap[p]+' = '+this.format(p)+';\n';
}, this).join('');
return [ 'var ws = WScript.CreateObject("WScript.Shell");',
'var s = ws.CreateShortcut(' + this.format('location') + ' + "\\\\' + this.format('title')+'");',
properties,
's.Save(); WScript.Echo(s);' ].join('\n');
},
format: function(name){
return formatters[name].call(this, this[name]);
}
};
Object.defineProperties(Shortcut.prototype, {
toString: { enumerable: false },
format: { enumerable: false },
create: { enumerable: false }
});
var propMap = {
target: 'TargetPath',
cwd: 'WorkingDirectory',
style: 'WindowStyle',
args: 'Arguments',
icon: 'IconLocation',
description: 'Description',
hotkey: 'Hotkey'
};
var q = ['"', "'"];
var qMatch = [/(')/g, /(")/g];
function quotes(s) {
if (typeof s === 'undefined') return "''";
s = String(s).replace(/\\/g, '\\\\');
var qWith = +(s.match(qMatch[0]) === null);
return q[qWith] + s.replace(qMatch[1-qWith], '\\$1') + q[qWith];
}
var formatters = {
location: function(v){
if (~special.indexOf(v)) {
return 'ws.SpecialFolders("'+v+'")';
} else {
return quotes(path.resolve(v));
}
},
style: function(v){
var index = styles.indexOf(this.style);
return ~index ? index : 1;
},
title: function(v){
return path.basename((v || this.target).slice(0, this.target.indexOf('.') + 1) + 'lnk');
},
cwd: function(v){
return quotes(path.resolve(this.target).slice(0, -path.basename(this.target).length));
},
target: quotes,
args: quotes,
description: quotes,
hotkey: quotes
}
/*
var HIDDEN = 0x1000;
var struct = {
labels: [ HIDDEN, 'uuid', 'flags', 'attributes', ],
data: [ uint32, string(16), uint32, uint32, uint32, uint32, uint32, uint32, uint32, uint32, uint32 ]
}
0x000214010000000000C0000000000046
1 Uint32 Always 0000004Ch ‘L’
16 bytes uuid
1 Uint32 Flags
1 Uint32 File attributes
1 Uint32 Time 1
1 Uint32 Time 2
1 Uint32 Time 3
1 Uint32 File length
1 Uint32 Icon number
1 Uint32 ShowWnd value
1 Uint32 Hot key
2 Uint32 Unknown, always zero
http://ithreats.files.wordpress.com/2009/05/lnk_the_windows_shortcut_file_format.pdf
*/