source: Daodan/MinGW/libexec/mingw-get/shlink.js@ 1046

Last change on this file since 1046 was 1046, checked in by alloc, 8 years ago

Daodan: Added Windows MinGW and build batch file

File size: 10.7 KB
Line 
1/*
2 * shlink.js
3 *
4 * $Id: shlink.js,v 0f864a5cad9e 2012/04/06 22:49:36 keithmarshall $
5 *
6 * Invoke the Windows Scripting Host to create or modify a windows shortcut,
7 * with specified parameters.
8 *
9 * Usage:
10 * cscript -nologo shlink.js [--option[=value] ...] target name
11 *
12 * Options:
13 * --verbose report shortcut parameter assignments on stdout
14 *
15 * --all-users
16 * create the shortcut in the start menu, or on the
17 * desktop available to all users; (has no effect,
18 * unless --start-menu or --desktop is specified)
19 *
20 * --desktop create the shortcut on the desktop of the current
21 * user, (or for all users, with --all-users)
22 *
23 * --start-menu
24 * create the shortcut in the user's start menu, (or
25 * all users' start menu, with --all-users)
26 *
27 * --arguments="argument list ..."
28 * specify arguments to be passed to the command
29 * invoked by the shortcut
30 *
31 * --description="text ..."
32 * specify the "tool tip" for the shortcut
33 *
34 * --hotkey="[SHIFT+][CTRL+][ALT+]key"
35 * specify a hot-key combination which may be used
36 * to invoke the shortcut command
37 *
38 * --icon="d:\path\to\icon\file[,index]"
39 * specify an icon to associate with the shortcut;
40 * if unspecified, the first icon in the target file,
41 * or failing that, a system default is used
42 *
43 * --show=normal|maximised|minimised
44 * specify the style of window in which the program
45 * invoked by the shortcut will start running
46 *
47 * --workingdir="d:\path\to\working\directory"
48 * specify the absolute path name for the directory
49 * which will become the current working directory when
50 * the program invoked by the shortcut is started
51 *
52 * Parameters:
53 * target the path name to the program to invoke, or the file
54 * to be opened, when the shortcut is activated.
55 *
56 * name the path name for the shortcut file itself; if this
57 * does not end with either a ".lnk" or ".url" extension,
58 * then ".lnk" will be appended, so creating a regular
59 * file system link type shortcut.
60 *
61 *
62 * This file is a component of mingw-get.
63 *
64 * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
65 * Copyright (C) 2012, MinGW Project
66 *
67 *
68 * Permission is hereby granted, free of charge, to any person obtaining a
69 * copy of this software and associated documentation files (the "Software"),
70 * to deal in the Software without restriction, including without limitation
71 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
72 * and/or sell copies of the Software, and to permit persons to whom the
73 * Software is furnished to do so, subject to the following conditions:
74 *
75 * The above copyright notice and this permission notice shall be included
76 * in all copies or substantial portions of the Software.
77 *
78 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
79 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
80 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
81 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
82 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
83 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
84 * DEALINGS IN THE SOFTWARE.
85 *
86 */
87var cmdName = WScript.ScriptName;
88var WinShell = WScript.CreateObject("WScript.Shell");
89
90/* Properties for the shortcut may be specified as arguments
91 * to command line options, each of which is represented in the
92 * GNU long option form, by keywords with property associations
93 * as specified by:
94 */
95var options = Array(
96 "name", /* File name/path of .lnk file */
97 "all-users",
98 "start-menu",
99 "desktop",
100 "verbose",
101 /*
102 * Option Property
103 * ------------- -------------------------
104 */
105 "arguments", /* Shortcut.Arguments */
106 "description", /* Shortcut.Description */
107 "hotkey", /* Shortcut.HotKey */
108 "icon", /* Shortcut.IconLocation */
109 "show", /* Shortcut.WindowStyle */
110 "target", /* Shortcut.TargetPath */
111 "workingdir" /* Shortcut.WorkingDirectory */
112 );
113
114/* The "complain" function provides a mechanism for writing
115 * diagnostic messages to stderr, and optionally aborting the
116 * calling script.
117 */
118function complain( condition, message )
119{
120 WScript.StdErr.WriteLine( cmdName + ": " + message );
121 if( condition < 0 )
122 WScript.Quit( -condition );
123 return condition;
124}
125
126/* Strip ".js" suffix from command name.
127 */
128var i = cmdName.lastIndexOf( ".js" );
129if( (i > 0) && (cmdName.substr( i ) == ".js") )
130 cmdName = cmdName.substr( 0, i );
131
132/* Initialise all options to "unassigned" state.
133 */
134var target = -1;
135var lnkname = -1;
136var desktop = -1;
137var allusers = -1;
138var startmenu = -1;
139var verbosity = -1;
140var unassigned = "+++unassigned+++";
141var assigned = Array( options.length );
142for( var k = 0; k < assigned.length; k++ )
143{
144 switch( options[k] )
145 {
146 case "name":
147 lnkname = k;
148 break;
149
150 case "desktop":
151 desktop = k;
152 break;
153
154 case "start-menu":
155 startmenu = k;
156 break;
157
158 case "all-users":
159 allusers = k;
160 break;
161
162 case "target":
163 target = k;
164 break;
165
166 case "verbose":
167 verbosity = k;
168 }
169 assigned[k] = unassigned;
170}
171
172/* Define the prefix, which will qualify the location
173 * of the shortcut; initialise it to nothing, so that by
174 * default shortcuts will be located by absolute path name,
175 * as specified, or relative to current working directory.
176 */
177var prefix = "";
178
179var j;
180function assign_option( name, value )
181{
182 switch( name )
183 {
184 case "desktop":
185 case "start-menu":
186 case "all-users":
187 case "verbose":
188 j = i;
189 return "set";
190 }
191 return value;
192}
193
194/* Parse the command line.
195 */
196var argv = WScript.Arguments;
197for( i = 0; i < argv.length; i++ )
198{
199 if( argv( i ).indexOf( "--" ) == 0 )
200 {
201 /* Handle arguments specifying options...
202 */
203 if( (optind = argv( j = i ).indexOf( "=" ) + 1) > 3 )
204 {
205 optnam = argv( j ).substr( 2, optind - 3 );
206 optarg = argv( j ).substr( optind );
207 }
208 else
209 {
210 optnam = argv( j ).substr( 2 );
211 if( ++j < argv.length )
212 optarg = argv( j );
213 else
214 optarg = unassigned;
215 }
216
217 var matched = 0;
218 for( var k = 0; k < options.length; k++ )
219 {
220 if( optnam == options[k] )
221 {
222 matched = 1;
223 assigned[k] = assign_option( options[k], optarg );
224 k = options.length;
225 }
226 else if( options[k].indexOf(optnam) == 0 )
227 {
228 if( ++matched > 1 )
229 complain( -2, cmdName + "option '" + argv( i ) + "' is ambiguous" );
230 assigned[k] = assign_option( options[k], optarg );
231 }
232 }
233 if( matched == 1 )
234 {
235 i = j;
236 }
237 else
238 complain( -2, "option '" + argv( i ) + "' is not supported" );
239 }
240
241 /* Handle non-option arguments...
242 */
243 else if( (target >= 0) && (assigned[target] == unassigned) )
244 /*
245 * ...the first of which is the target to which the
246 * (shortcut) link is to refer...
247 */
248 assigned[target] = argv( i );
249
250 else if( (lnkname >= 0) && (assigned[lnkname] == unassigned) )
251 /*
252 * ...the second is the file system path name at which
253 * the link file itself is to be saved...
254 */
255 assigned[lnkname] = argv( i );
256
257 else
258 /* ...and any more than two is an error.
259 */
260 complain( -2, "too many arguments" );
261}
262
263/* Verify that mandatory arguments have been specified...
264 */
265if( assigned[target] == unassigned )
266 /*
267 * First of these, the TargetPath specification, is required;
268 * diagnose and abort, if missing.
269 */
270 complain( -2, "missing argument: no target path specified" );
271
272if( assigned[lnkname] == unassigned )
273 /*
274 * Second, the path name for the link file itself is essential;
275 * again, diagnose and abort if missing.
276 */
277 complain( -2, "missing argument: no shortcut name specified" );
278
279/* We have both the mandatory arguments; check that the link name
280 * is properly terminated by a ".lnk" or ".url" suffix...
281 */
282var suffix = "";
283if( (i = assigned[lnkname].length - 4) > 0 )
284 suffix = assigned[lnkname].substr( i );
285
286/* ...and append ".lnk" as default, if not already present.
287 */
288if( (suffix != ".lnk") && (suffix != ".url") )
289 assigned[lnkname] += ".lnk";
290
291/* Add the appropriate prefix for '--desktop' or '--start-menu' shortcuts.
292 */
293if( assigned[desktop] != unassigned )
294{
295 if( assigned[startmenu] != unassigned )
296 complain( -2, "options '--desktop' and '--start-menu' are incompatible" );
297 else prefix = WinShell.SpecialFolders( (assigned[allusers] == unassigned)
298 ? "Desktop" : "AllUsersDesktop" ) + "\\";
299}
300else if( assigned[startmenu] != unassigned )
301 prefix = WinShell.SpecialFolders( (assigned[allusers] == unassigned)
302 ? "StartMenu" : "AllUsersStartMenu" ) + "\\";
303
304else if( assigned[allusers] != unassigned )
305 complain( -2,
306 "option '--all-users' also requires '--desktop' or '--start-menu'"
307 );
308
309/* Handle verbosity...
310 */
311function verbose_assignment( property, value )
312{
313 if( assigned[verbosity] == "set" )
314 WScript.Echo( cmdName + ": set " + property + " = " + value );
315}
316
317/* Initialise the shortcut entity reference.
318 */
319if( assigned[verbosity] == "set" )
320 WScript.Echo( cmdName + ": create shortcut: " + prefix + assigned[lnkname] );
321
322var Shortcut = WinShell.CreateShortcut( prefix + assigned[lnkname] );
323
324for( var k = 0; k < options.length; k++ )
325{
326 if( assigned[k] != unassigned )
327 switch( options[k] )
328 {
329 case "arguments":
330 verbose_assignment( "Shortcut.Arguments", assigned[k] );
331 Shortcut.Arguments = assigned[k];
332 break;
333
334 case "description":
335 verbose_assignment( "Shortcut.Description", assigned[k] );
336 Shortcut.Description = assigned[k];
337 break;
338
339 case "hotkey":
340 verbose_assignment( "Shortcut.HotKey", assigned[k] );
341 Shortcut.HotKey = assigned[k];
342 break;
343
344 case "icon":
345 verbose_assignment( "Shortcut.IconLocation", assigned[k] );
346 Shortcut.IconLocation = assigned[k];
347 break;
348
349 case "show":
350 verbose_assignment( "Shortcut.WindowStyle", assigned[k] );
351 var style = Array(
352 "normal", 1,
353 "maximised", 3,
354 "maximized", 3,
355 "minimised", 7,
356 "minimized", 7
357 );
358 for( j = 0; j < style.length; j++ )
359 if( style[j++].indexOf( assigned[k] ) == 0 )
360 {
361 Shortcut.WindowStyle = style[j];
362 j = 100;
363 }
364 if( j < 100 )
365 complain( 1, "unrecognised mode '--show=" + assigned[k] + "' ignored" );
366 break;
367
368 case "target":
369 verbose_assignment( "Shortcut.TargetPath", assigned[k] );
370 Shortcut.TargetPath = assigned[k];
371 break;
372
373 case "workingdir":
374 verbose_assignment( "Shortcut.WorkingDirectory", assigned[k] );
375 Shortcut.WorkingDirectory = assigned[k];
376 }
377 else if( assigned[verbosity] == "set" )
378 WScript.Echo( cmdName + ": option '--" + options[k] + "' is unassigned" );
379}
380
381/* Commit the shortcut entity to disk.
382 */
383Shortcut.Save();
384
385/* $RCSfile: shlink.js,v $: end of file */
Note: See TracBrowser for help on using the repository browser.