root / import / ext3D / trunk / install-extension3d / IzPack / src / lib / com / izforge / izpack / util / os / ShellLink.java @ 15280
History | View | Annotate | Download (38.1 KB)
1 |
/*
|
---|---|
2 |
* $Id: ShellLink.java,v 1.1 2006/06/14 07:29:07 cesar Exp $
|
3 |
* IzPack
|
4 |
* Copyright (C) 2002 by Elmar Grom
|
5 |
*
|
6 |
* File : ShellLink.java
|
7 |
* Description : Represents a MS-Windows Shell Link (shortcut)
|
8 |
* This is the Java side of the implementation
|
9 |
* Author's email : elmar@grom.net
|
10 |
* Website : http://www.izforge.com
|
11 |
*
|
12 |
* This program is free software; you can redistribute it and/or
|
13 |
* modify it under the terms of the GNU General Public License
|
14 |
* as published by the Free Software Foundation; either version 2
|
15 |
* of the License, or any later version.
|
16 |
*
|
17 |
* This program is distributed in the hope that it will be useful,
|
18 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
19 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
20 |
* GNU General Public License for more details.
|
21 |
*
|
22 |
* You should have received a copy of the GNU General Public License
|
23 |
* along with this program; if not, write to the Free Software
|
24 |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
25 |
*/
|
26 |
|
27 |
package com.izforge.izpack.util.os; |
28 |
|
29 |
import java.io.File; |
30 |
|
31 |
import com.izforge.izpack.util.Librarian; |
32 |
import com.izforge.izpack.util.NativeLibraryClient; |
33 |
|
34 |
/*---------------------------------------------------------------------------*/
|
35 |
/**
|
36 |
* This class represents a MS-Windows shell link, aka shortcut. It
|
37 |
* supports creation, modification and deletion as well as reporting on
|
38 |
* details of shell links. This class uses a number of native methods to
|
39 |
* access the MS-Windows registry and load save and manipulate link data.
|
40 |
* The native code is contained in the file <code>ShellLink.cpp</code>.
|
41 |
* <br><br>
|
42 |
* For more detailed information on Windows shortcuts read the win32
|
43 |
* documentation from Microsoft on the IShellLink interface. There are
|
44 |
* also useful articles on this topic on the MIcrosoft website.
|
45 |
* <br><br>
|
46 |
* <A HREF=http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnmgmt/html/msdn_shellnk1.asp>Using Shell Links in Windows 95</A><br>
|
47 |
* <A HREF=http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/ifaces/ishelllink/ishelllink.asp>The IShellLink interface</a><br>
|
48 |
* <A HREF=http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/Shell/IFaces/IShellLink/IShellLink.asp>IShellLink</A>
|
49 |
*
|
50 |
* @version 0.0.1 / 1/21/02
|
51 |
* @author Elmar Grom
|
52 |
*/
|
53 |
/*---------------------------------------------------------------------------*/
|
54 |
public class ShellLink implements NativeLibraryClient |
55 |
{ |
56 |
// ------------------------------------------------------------------------
|
57 |
// Constant Definitions
|
58 |
// ------------------------------------------------------------------------
|
59 |
/** Note: each of the subclasses will convert these values as appropriate
|
60 |
before calling the OS's routines. For example Win 98 & up will use
|
61 |
SW_SNOWMINNOACTIVE (7) when passed HIDE (0) or MINIMIZED (2) <br><br>
|
62 |
and this conversion is done in Win_Shortcut.java */
|
63 |
/** Hide the window when starting. This is particularly useful when
|
64 |
launching from a *.bat file, because no DOS window and no button
|
65 |
for the DOS window on the task bar will show!
|
66 |
<br><br>
|
67 |
<b>Note:</b> this option is not available through the Windows 98+ UI! */
|
68 |
public static final int HIDE = 0; |
69 |
/** Show the window 'normal' when starting. Restores the window properties
|
70 |
at the last shut-down. */
|
71 |
public static final int NORMAL = 1; |
72 |
/** Show the window minimized when starting. The window will not show but
|
73 |
a corresponding button in the task bar will. */
|
74 |
/** newer IShellLink only allows Normal, MinNoActive, Maximized. */
|
75 |
public static final int MINIMIZED = 2; |
76 |
/** Show the window maximized when starting. */
|
77 |
public static final int MAXIMIZED = 3; |
78 |
/** Show the window minimized when starting.
|
79 |
note- for win98 and newer,
|
80 |
use MINNOACTIVE instead of MINIMIZED */
|
81 |
public static final int MINNOACTIVE = 7; |
82 |
|
83 |
private static final int MIN_SHOW = 0; |
84 |
private static final int MAX_SHOW = 7; |
85 |
|
86 |
// ------------------------------------------------------
|
87 |
// Shortcut types
|
88 |
// specific to ShellLink (Shortcut has different numbers).
|
89 |
// ------------------------------------------------------
|
90 |
/** This type of shortcut shows on the desktop */
|
91 |
public static final int DESKTOP = 1; |
92 |
/** This type of shortcut shows in the program menu */
|
93 |
public static final int PROGRAM_MENU = 2; |
94 |
/** This type of shortcut shows in the start menu */
|
95 |
public static final int START_MENU = 3; |
96 |
/** This type of shortcut is executed at OS launch time */
|
97 |
public static final int STARTUP = 4; |
98 |
|
99 |
private static final int MIN_TYPE = 1; |
100 |
private static final int MAX_TYPE = 4; |
101 |
|
102 |
// ------------------------------------------------------
|
103 |
// Return values from nafive methods
|
104 |
// ------------------------------------------------------
|
105 |
/** Returned from native calls if the call was successful */
|
106 |
private static final int SL_OK = 1; |
107 |
/** Unspecific return if a native call was not successful */
|
108 |
private static final int SL_ERROR = -1; |
109 |
/** Return value from native initialization functions if
|
110 |
already initialized */
|
111 |
private static final int SL_INITIALIZED = -2; |
112 |
/** Return value from native uninitialization functions if
|
113 |
never initialized */
|
114 |
private static final int SL_NOT_INITIALIZED = -3; |
115 |
/** Return value from native uninitialization functions if
|
116 |
there are no more interface handles available */
|
117 |
private static final int SL_OUT_OF_HANDLES = -4; |
118 |
/** Return value from native uninitialization functions if
|
119 |
nohandle for the IPersist interface could be obtained */
|
120 |
private static final int SL_NO_IPERSIST = -5; |
121 |
/** Return value from native uninitialization functions if
|
122 |
the save operation fort the link failed */
|
123 |
private static final int SL_NO_SAVE = -6; |
124 |
/** Return value if the function called had to deal with
|
125 |
unexpected data types. This might be returned by
|
126 |
registry functions if they receive an unexpected
|
127 |
data type from the registry. */
|
128 |
private static final int SL_WRONG_DATA_TYPE = -7; |
129 |
|
130 |
// ------------------------------------------------------
|
131 |
// Miscellaneous constants
|
132 |
// ------------------------------------------------------
|
133 |
private static final int UNINITIALIZED = -1; |
134 |
/** the extension that must be used for link files */
|
135 |
private static final String LINK_EXTENSION = ".lnk"; |
136 |
/** the constant to use for selecting the current user. */
|
137 |
public static final int CURRENT_USER = 0; |
138 |
/** the constant to use for selecting the all users. */
|
139 |
public static final int ALL_USERS = 1; |
140 |
|
141 |
// ------------------------------------------------------------------------
|
142 |
// Variable Declarations
|
143 |
// ------------------------------------------------------------------------
|
144 |
/** This handle links us to a specific native instance. Do not use or
|
145 |
modify, the variable is for exclusive use by the native side. */
|
146 |
private int nativeHandle = UNINITIALIZED; |
147 |
|
148 |
/** Path to the location where links for the current user are stored. The
|
149 |
exact content depends on the circumstances. It can be set during object
|
150 |
construction or from native code. It will point to the location where
|
151 |
links of the most recently requested type are stored. */
|
152 |
private String currentUserLinkPath = ""; |
153 |
/** Path to the location where links for all users are stored. The exact
|
154 |
content depends on the circumstances. It can be set during object
|
155 |
construction or from native code. It will point to the location where
|
156 |
links of the most recently requested type are stored. */
|
157 |
private String allUsersLinkPath = ""; |
158 |
private String groupName = ""; |
159 |
private String linkName = ""; |
160 |
/** this is the fully qualified name of the link on disk. Note that this
|
161 |
variable contains only valid data if the link was created from a disk
|
162 |
file or after a successful save operation. At other times the content
|
163 |
is upredicatable. */
|
164 |
private String linkFileName = ""; |
165 |
/** Contains the directory where the link file is stored after any save
|
166 |
operation that needs to create that directory. Otherwise it contains
|
167 |
<code>null</code>. */
|
168 |
private String linkDirectory = ""; |
169 |
|
170 |
private String arguments = ""; |
171 |
private String description = ""; |
172 |
private String iconPath = ""; |
173 |
private String targetPath = ""; |
174 |
private String workingDirectory = ""; |
175 |
/** there seems to be an error in JNI that causes an access violation if
|
176 |
a String that is accessed from native code borders on another type of
|
177 |
variable. This caused problems in <code>set()</code> For this reason,
|
178 |
the dummy string is placed here. Observed with version: <pre>
|
179 |
java version "1.3.0"
|
180 |
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
|
181 |
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode) </pre> */
|
182 |
private String dummyString = ""; |
183 |
|
184 |
private int hotkey = 0; |
185 |
private int iconIndex = 0; |
186 |
private int showCommand = NORMAL; |
187 |
private int linkType = DESKTOP; |
188 |
private int userType = CURRENT_USER; |
189 |
|
190 |
private boolean initializeSucceeded = false; |
191 |
|
192 |
// ------------------------------------------------------------------------
|
193 |
// Native Methods
|
194 |
// ------------------------------------------------------------------------
|
195 |
// For documentation on these methods see ShellLink.cpp
|
196 |
// ------------------------------------------------------------------------
|
197 |
private native int initializeCOM (); |
198 |
private native int releaseCOM (); |
199 |
private native int getInterface (); |
200 |
private native int releaseInterface (); |
201 |
private native int GetArguments (); |
202 |
private native int GetDescription (); |
203 |
private native int GetHotkey (); |
204 |
private native int GetIconLocation (); |
205 |
private native int GetPath (); |
206 |
private native int GetShowCommand (); |
207 |
private native int GetWorkingDirectory (); |
208 |
private native int Resolve (); |
209 |
private native int SetArguments (); |
210 |
private native int SetDescription (); |
211 |
private native int SetHotkey (); |
212 |
private native int SetIconLocation (); |
213 |
private native int SetPath (); |
214 |
private native int SetShowCommand (); |
215 |
private native int SetWorkingDirectory (); |
216 |
private native int saveLink (String name); |
217 |
private native int loadLink (String name); |
218 |
private native int GetFullLinkPath (int usertype, int linktype); |
219 |
|
220 |
/**
|
221 |
* This method is used to free the library at the end of progam execution.
|
222 |
* After this call, any instance of this calss will not be usable any more!
|
223 |
*/
|
224 |
private native void FreeLibrary (String name); |
225 |
|
226 |
/**
|
227 |
* Creates an instance of <code>ShellLink</code> of a specific
|
228 |
* type. Initializes currentUserLinkPath and allUsersLinkPath.<p>
|
229 |
*
|
230 |
* A LinkPath is empty if the combination of linkType and userType, are not
|
231 |
* valid.<p>
|
232 |
*
|
233 |
* Note: If a linkPath is empty, the userType is reset to the other
|
234 |
* userType.<p>
|
235 |
*
|
236 |
* If both linkPaths are empty, an IllegalArgumentException is thrown.
|
237 |
*
|
238 |
* @param type The type of link desired. The following values can be set:<br>
|
239 |
* <ul>
|
240 |
* <li><code>ShellLink.DESKTOP</code>
|
241 |
* <li><code>ShellLink.PROGRAM_MENU</code>
|
242 |
* <li><code>ShellLink.START_MENU</code>
|
243 |
* <li><code>ShellLink.STARTUP</code>
|
244 |
* </ul>
|
245 |
* @param name The name that the link should display on a menu or on
|
246 |
* the desktop. Do not include a file extension.
|
247 |
*
|
248 |
* @exception IllegalArgumentException if any of the call parameters are
|
249 |
* incorrect, or if no linkPaths are returned.
|
250 |
* @exception Exception if problems are encountered in initializing the
|
251 |
* native interface
|
252 |
*/
|
253 |
public ShellLink (int type, |
254 |
String name) throws Exception, IllegalArgumentException |
255 |
{ |
256 |
if ((type < MIN_TYPE) ||
|
257 |
(type > MAX_TYPE) ) |
258 |
{ |
259 |
throw (new IllegalArgumentException ("the type parameter used an illegal value")); |
260 |
} |
261 |
if (name == null) |
262 |
{ |
263 |
throw (new IllegalArgumentException ("the name parameter was null")); |
264 |
} |
265 |
|
266 |
linkName = name; |
267 |
linkType = type; |
268 |
|
269 |
initialize (); //com
|
270 |
|
271 |
// set curretnUsersLinkPath, allUsersLinkPath, sets userType to valid.
|
272 |
setAllLinkPaths(); |
273 |
} |
274 |
|
275 |
/*--------------------------------------------------------------------------*/
|
276 |
/**
|
277 |
* Creates an instance of <code>ShellLink</code> from an existing shell link
|
278 |
* on disk.
|
279 |
*
|
280 |
* @param name the fully qualified file name of the link.
|
281 |
* @param userType the type of user for the link path.
|
282 |
*
|
283 |
* @see #CURRENT_USER
|
284 |
* @see #ALL_USERS
|
285 |
*
|
286 |
* @exception IllegalArgumentException if the name was null
|
287 |
* @exception Exception if problems are encountered in reading the file
|
288 |
*/
|
289 |
public ShellLink (String name, |
290 |
int userType) throws Exception, IllegalArgumentException |
291 |
{ |
292 |
if (name == null) |
293 |
{ |
294 |
throw (new IllegalArgumentException ("the name parameter was null")); |
295 |
} |
296 |
|
297 |
this.userType = userType;
|
298 |
|
299 |
initialize (); //com
|
300 |
|
301 |
// store the individual parts of the path for later use
|
302 |
int pathEnd = name.lastIndexOf (File.separator); |
303 |
int nameStart = pathEnd + 1; |
304 |
int nameEnd = name.lastIndexOf ('.'); |
305 |
if (nameEnd < 0) |
306 |
{ |
307 |
throw (new Exception ("illegal file name")); |
308 |
} |
309 |
linkName = name.substring (nameStart, nameEnd); |
310 |
|
311 |
if (userType == CURRENT_USER)
|
312 |
{ |
313 |
currentUserLinkPath = name.substring (0, pathEnd);
|
314 |
} |
315 |
else
|
316 |
{ |
317 |
allUsersLinkPath = name.substring (0, pathEnd);
|
318 |
} |
319 |
|
320 |
linkFileName = fullLinkName (userType); |
321 |
if (loadLink (linkFileName) != SL_OK)
|
322 |
{ |
323 |
throw (new Exception ("reading of the file did not succeed")); |
324 |
} |
325 |
|
326 |
// get all settings from the native side
|
327 |
get (); |
328 |
} |
329 |
|
330 |
/*--------------------------------------------------------------------------*/
|
331 |
/**
|
332 |
* Creates an instance of <code>ShellLink</code> from an existing shell link
|
333 |
* on disk.
|
334 |
*
|
335 |
* @param type The type of link, one of the following values: <br>
|
336 |
* <ul>
|
337 |
* <li><code>ShellLink.DESKTOP</code>
|
338 |
* <li><code>ShellLink.PROGRAM_MENU</code>
|
339 |
* <li><code>ShellLink.START_MENU</code>
|
340 |
* <li><code>ShellLink.STARTUP</code>
|
341 |
* </ul>
|
342 |
* @param userType the type of user for the link path.
|
343 |
* @param group The program group (directory) of this link. If the
|
344 |
* link is not part of a program group, pass an empty
|
345 |
* string or null for this parameter. (...\\Desktop\\group).
|
346 |
* @param name The file name of this link. Do not include a file
|
347 |
* extension.
|
348 |
*
|
349 |
* @see #CURRENT_USER
|
350 |
* @see #ALL_USERS
|
351 |
*
|
352 |
* @exception IllegalArgumentException if any of the call parameters are
|
353 |
* incorrect
|
354 |
* @exception Exception if problems are encountered in initializing the
|
355 |
* native interface
|
356 |
*/
|
357 |
public ShellLink (int type, |
358 |
int userType,
|
359 |
String group,
|
360 |
String name) throws Exception, IllegalArgumentException |
361 |
{ |
362 |
if ((type < MIN_TYPE) ||
|
363 |
(type > MAX_TYPE) ) |
364 |
{ |
365 |
throw (new IllegalArgumentException ("the type parameter used an illegal value")); |
366 |
} |
367 |
if (name == null) |
368 |
{ |
369 |
throw (new IllegalArgumentException ("the name parameter was null")); |
370 |
} |
371 |
|
372 |
this.userType = userType;
|
373 |
|
374 |
initialize (); //com
|
375 |
|
376 |
// set the variables for currentUserLinkPath and allUsersLinkPath
|
377 |
setAllLinkPaths(); |
378 |
|
379 |
if (group != null) |
380 |
{ |
381 |
groupName = group; |
382 |
} |
383 |
linkName = name; |
384 |
|
385 |
// load the link
|
386 |
linkFileName = fullLinkName (userType); |
387 |
if (loadLink(linkFileName) != SL_OK)
|
388 |
{ |
389 |
throw (new Exception ("reading of the file did not succeed")); |
390 |
} |
391 |
|
392 |
// get a settings from the native side
|
393 |
get (); |
394 |
} |
395 |
|
396 |
/*--------------------------------------------------------------------------*/
|
397 |
/**
|
398 |
* Initializes COM and gets an instance of the IShellLink interface.
|
399 |
*
|
400 |
* @exception Exception if problems are encountered
|
401 |
*/
|
402 |
private void initialize () throws Exception |
403 |
{ |
404 |
try
|
405 |
{ |
406 |
Librarian.getInstance ().loadLibrary ("ShellLink", this); |
407 |
} |
408 |
catch (UnsatisfiedLinkError exception) |
409 |
{ |
410 |
throw (new Exception ("could not locate native library")); |
411 |
} |
412 |
|
413 |
try
|
414 |
{ |
415 |
if (initializeCOM () != SL_OK)
|
416 |
{ |
417 |
throw (new Exception ("could not initialize COM")); |
418 |
} |
419 |
else
|
420 |
{ |
421 |
initializeSucceeded = true;
|
422 |
} |
423 |
} |
424 |
catch (Throwable exception) |
425 |
{ |
426 |
throw (new Exception ("unidentified problem initializing COM\n" + exception.toString ())); |
427 |
} |
428 |
|
429 |
int successCode = getInterface ();
|
430 |
if (successCode != SL_OK)
|
431 |
{ |
432 |
releaseCOM (); |
433 |
initializeSucceeded = false;
|
434 |
|
435 |
if (successCode == SL_OUT_OF_HANDLES)
|
436 |
{ |
437 |
throw (new Exception ("could not get an instance of IShellLink, no more handles available")); |
438 |
} |
439 |
else
|
440 |
{ |
441 |
throw (new Exception ("could not get an instance of IShellLink, failed to co-create instance")); |
442 |
} |
443 |
} |
444 |
} |
445 |
|
446 |
/*--------------------------------------------------------------------------*/
|
447 |
/**
|
448 |
* Destructor, releases COM and frees native resources.
|
449 |
*/
|
450 |
protected void finalize () |
451 |
{ |
452 |
releaseInterface (); |
453 |
|
454 |
if (initializeSucceeded)
|
455 |
{ |
456 |
releaseCOM (); |
457 |
initializeSucceeded = false;
|
458 |
} |
459 |
} |
460 |
|
461 |
/*--------------------------------------------------------------------------*/
|
462 |
/**
|
463 |
* This method is used to free the library at the end of progam execution.
|
464 |
* After this call, any instance of this calss will not be usable any more!
|
465 |
* <b><i><u>Note that this method does NOT return!</u></i></b>
|
466 |
* <br><br>
|
467 |
* <b>DO NOT CALL THIS METHOD DIRECTLY!</b><br>
|
468 |
* It is used by the librarian to free the native library before physically
|
469 |
* deleting it from its temporary loaction. A call to this method will
|
470 |
* freeze the application irrecoverably!
|
471 |
*
|
472 |
* @param name the name of the library to free. Use only the name and
|
473 |
* extension but not the path.
|
474 |
*
|
475 |
* @see com.izforge.izpack.util.NativeLibraryClient#freeLibrary
|
476 |
*/
|
477 |
public void freeLibrary (String name) |
478 |
{ |
479 |
int result = releaseInterface ();
|
480 |
|
481 |
if (initializeSucceeded)
|
482 |
{ |
483 |
result = releaseCOM (); |
484 |
initializeSucceeded = false;
|
485 |
} |
486 |
|
487 |
FreeLibrary (name); |
488 |
} |
489 |
|
490 |
/*--------------------------------------------------------------------------*/
|
491 |
/**
|
492 |
* Constructs and returns the full path for the link file.
|
493 |
*
|
494 |
* @param userType the type of user for the link path.
|
495 |
*
|
496 |
* @return the path to use for storing the link
|
497 |
*
|
498 |
* @see #CURRENT_USER
|
499 |
* @see #ALL_USERS
|
500 |
*/
|
501 |
private String fullLinkPath (int userType) |
502 |
{ |
503 |
StringBuffer path = new StringBuffer (); |
504 |
|
505 |
// ----------------------------------------------------
|
506 |
// build the complete name
|
507 |
// ----------------------------------------------------
|
508 |
if (userType == CURRENT_USER)
|
509 |
{ |
510 |
path.append (currentUserLinkPath); |
511 |
} |
512 |
else
|
513 |
{ |
514 |
path.append (allUsersLinkPath); |
515 |
} |
516 |
|
517 |
if ((groupName != null) && (groupName.length () > 0)) |
518 |
{ |
519 |
path.append (File.separator);
|
520 |
path.append (groupName); |
521 |
} |
522 |
|
523 |
return (path.toString ());
|
524 |
} |
525 |
|
526 |
/*--------------------------------------------------------------------------*/
|
527 |
/**
|
528 |
* Constructs and returns the fully qualified name for the link file.
|
529 |
*
|
530 |
* @param userType the type of user for the link path.
|
531 |
*
|
532 |
* @return the fully qualified file name to use for storing the link
|
533 |
*
|
534 |
* @see #CURRENT_USER
|
535 |
* @see #ALL_USERS
|
536 |
*/
|
537 |
private String fullLinkName (int userType) |
538 |
{ |
539 |
StringBuffer name = new StringBuffer (); |
540 |
|
541 |
name.append (fullLinkPath (userType)); |
542 |
|
543 |
name.append (File.separator);
|
544 |
name.append (linkName); |
545 |
name.append (LINK_EXTENSION); |
546 |
|
547 |
return (name.toString ());
|
548 |
} |
549 |
|
550 |
/*--------------------------------------------------------------------------*/
|
551 |
/**
|
552 |
* Sets all members on the native side.
|
553 |
*
|
554 |
* @exception Exception if any problem is encountered during this operation.
|
555 |
*/
|
556 |
private void set () throws Exception |
557 |
{ |
558 |
if (SetArguments () != SL_OK)
|
559 |
{ |
560 |
throw (new Exception ("could not set arguments")); |
561 |
} |
562 |
if (SetDescription () != SL_OK)
|
563 |
{ |
564 |
throw (new Exception ("could not set description")); |
565 |
} |
566 |
if (SetHotkey () != SL_OK)
|
567 |
{ |
568 |
throw (new Exception ("could not set hotkey")); |
569 |
} |
570 |
if (SetIconLocation () != SL_OK)
|
571 |
{ |
572 |
throw (new Exception ("could not set icon location")); |
573 |
} |
574 |
if (SetPath () != SL_OK)
|
575 |
{ |
576 |
throw (new Exception ("could not set target path")); |
577 |
} |
578 |
if (SetShowCommand () != SL_OK)
|
579 |
{ |
580 |
throw (new Exception ("could not set show command")); |
581 |
} |
582 |
if (SetWorkingDirectory () != SL_OK)
|
583 |
{ |
584 |
throw (new Exception ("could not set working directory")); |
585 |
} |
586 |
|
587 |
} |
588 |
|
589 |
/*--------------------------------------------------------------------------*/
|
590 |
/**
|
591 |
* Gets all members from the native side.
|
592 |
*
|
593 |
* @exception Exception if any problem is encountered during this operation.
|
594 |
*
|
595 |
*/
|
596 |
private void get () throws Exception |
597 |
{ |
598 |
if (GetArguments () != SL_OK)
|
599 |
{ |
600 |
throw (new Exception ("could not get arguments")); |
601 |
} |
602 |
if (GetDescription () != SL_OK)
|
603 |
{ |
604 |
throw (new Exception ("could not get description")); |
605 |
} |
606 |
if (GetHotkey () != SL_OK)
|
607 |
{ |
608 |
throw (new Exception ("could not get hotkey")); |
609 |
} |
610 |
if (GetIconLocation () != SL_OK)
|
611 |
{ |
612 |
throw (new Exception ("could not get icon location")); |
613 |
} |
614 |
if (GetPath () != SL_OK)
|
615 |
{ |
616 |
throw (new Exception ("could not get target ath")); |
617 |
} |
618 |
if (GetShowCommand () != SL_OK)
|
619 |
{ |
620 |
throw (new Exception ("could not get show command")); |
621 |
} |
622 |
if (GetWorkingDirectory () != SL_OK)
|
623 |
{ |
624 |
throw (new Exception ("could not get working directory")); |
625 |
} |
626 |
} |
627 |
|
628 |
/*--------------------------------------------------------------------------*/
|
629 |
/**
|
630 |
* Sets the name of the program group this ShellLinbk should be placed in.
|
631 |
*
|
632 |
* @param groupName the name of the program group
|
633 |
*/
|
634 |
public void setProgramGroup (String groupName) |
635 |
{ |
636 |
this.groupName = groupName;
|
637 |
} |
638 |
|
639 |
/*--------------------------------------------------------------------------*/
|
640 |
/**
|
641 |
* Sets the command line arguments that will be passed to the target when
|
642 |
* the link is activated.
|
643 |
*
|
644 |
* @param arguments the command line arguments
|
645 |
*
|
646 |
* @see #getArguments
|
647 |
*/
|
648 |
public void setArguments (String arguments) |
649 |
{ |
650 |
this.arguments = arguments;
|
651 |
} |
652 |
|
653 |
/*--------------------------------------------------------------------------*/
|
654 |
/**
|
655 |
* Sets the description string that is used to identify the link in a menu
|
656 |
* or on the desktop.
|
657 |
*
|
658 |
* @param description the descriptiojn string
|
659 |
*
|
660 |
* @see #getDescription
|
661 |
*/
|
662 |
public void setDescription (String description) |
663 |
{ |
664 |
this.description = description;
|
665 |
} |
666 |
|
667 |
/*--------------------------------------------------------------------------*/
|
668 |
/**
|
669 |
* Sets the hotkey that can be used to activate the link.
|
670 |
*
|
671 |
* @param hotkey a valid Windows virtual key code. Modifiers (e.g. for
|
672 |
* alt or shift key) are added in the upper byte. Note
|
673 |
* that only the lower 16 bits for tis parameter are used.
|
674 |
*
|
675 |
* @see #getHotkey
|
676 |
*/
|
677 |
public void setHotkey (int hotkey) |
678 |
{ |
679 |
this.hotkey = hotkey;
|
680 |
} |
681 |
|
682 |
/*--------------------------------------------------------------------------*/
|
683 |
/**
|
684 |
* Sets the location of the icon that is shown for the shortcut on the
|
685 |
* desktop.
|
686 |
*
|
687 |
* @param path a fully qualified file name of a file that contains
|
688 |
* the icon.
|
689 |
* @param index the index of the specific icon to use in the file.
|
690 |
* If there is only one icon in the file, use an index
|
691 |
* of 0.
|
692 |
*
|
693 |
* @see #getIconLocation
|
694 |
*/
|
695 |
public void setIconLocation (String path, |
696 |
int index)
|
697 |
{ |
698 |
this.iconPath = path;
|
699 |
this.iconIndex = index;
|
700 |
} |
701 |
|
702 |
/*--------------------------------------------------------------------------*/
|
703 |
/**
|
704 |
* Sets the absolute path to the shortcut target.
|
705 |
*
|
706 |
* @param path the fully qualified file name of the target
|
707 |
*
|
708 |
* @see #getTargetPath
|
709 |
*/
|
710 |
public void setTargetPath (String path) |
711 |
{ |
712 |
this.targetPath = path;
|
713 |
} |
714 |
|
715 |
/*--------------------------------------------------------------------------*/
|
716 |
/**
|
717 |
* Sets the show command that is passed to the target application when the
|
718 |
* link is activated. The show command determines if the the window will be
|
719 |
* restored to the previous size, minimized, maximized or visible at all.
|
720 |
* <br><br>
|
721 |
* <b>Note:</b><br>
|
722 |
* Using <code>HIDE</code> will cause the target window not to show at
|
723 |
* all. There is not even a button on the taskbar. This is a very useful
|
724 |
* setting when batch files are used to launch a Java application as it
|
725 |
* will then appear to run just like any native Windows application.<br>
|
726 |
* <b>Note1:</b><br>
|
727 |
* <code>HIDE</code> doesn't work in Win98 and newer systems.<br>
|
728 |
* use MINIMIZED (MINNOACTIVE), instead.<br>
|
729 |
*
|
730 |
* @param show the show command. Valid settings are: <br>
|
731 |
* <ul>
|
732 |
* <li><code>ShellLink.HIDE</code> (deprecated)
|
733 |
* <li><code>ShellLink.NORMAL</code>
|
734 |
* <li><code>ShellLink.MINNOACTIVE</code>
|
735 |
* <li><code>ShellLink.MAXIMIZED</code>
|
736 |
* </ul>
|
737 |
*
|
738 |
* @see #getShowCommand
|
739 |
*/
|
740 |
public void setShowCommand (int show) |
741 |
{ |
742 |
if ((show < MIN_SHOW) || (show > MAX_SHOW))
|
743 |
{ |
744 |
throw (new IllegalArgumentException ("illegal value for show command " + show)); |
745 |
} |
746 |
|
747 |
this.showCommand = show;
|
748 |
} |
749 |
|
750 |
/*--------------------------------------------------------------------------*/
|
751 |
/**
|
752 |
* Sets the working directory for the link target.
|
753 |
*
|
754 |
* @param dir the working directory
|
755 |
*
|
756 |
* @see #getWorkingDirectory
|
757 |
*/
|
758 |
public void setWorkingDirectory (String dir) |
759 |
{ |
760 |
this.workingDirectory = dir;
|
761 |
} |
762 |
|
763 |
/*--------------------------------------------------------------------------*/
|
764 |
/**
|
765 |
* Sets the name shown in a menu or on the desktop for the link.
|
766 |
*
|
767 |
* @param name The name that the link should display on a menu or on
|
768 |
* the desktop. Do not include a file extension.
|
769 |
*/
|
770 |
public void setLinkName (String name) |
771 |
{ |
772 |
linkName = name; |
773 |
} |
774 |
|
775 |
/*--------------------------------------------------------------------------*/
|
776 |
/**
|
777 |
* Sets the type of link
|
778 |
*
|
779 |
* @param type The type of link desired. The following values can be set:<br>
|
780 |
* <ul>
|
781 |
* <li>{@link #DESKTOP}
|
782 |
* <li>{@link #PROGRAM_MENU}
|
783 |
* <li>{@link #START_MENU}
|
784 |
* <li>{@link #STARTUP}
|
785 |
* </ul>
|
786 |
*
|
787 |
* @exception IllegalArgumentException if an an invalid type is passed
|
788 |
*/
|
789 |
public void setLinkType (int type) throws IllegalArgumentException |
790 |
{ |
791 |
if ((type < MIN_TYPE) ||
|
792 |
(type > MAX_TYPE) ) |
793 |
{ |
794 |
throw (new IllegalArgumentException ("illegal value for type")); |
795 |
} |
796 |
|
797 |
linkType = type; |
798 |
|
799 |
// set curretnUsersLinkPath, allUsersLinkPath, sets userType to valid.
|
800 |
setAllLinkPaths(); |
801 |
} |
802 |
|
803 |
/**
|
804 |
* Returns the user type for the link. <br>
|
805 |
* <ul>
|
806 |
* <li>{@link #DESKTOP}
|
807 |
* <li>{@link #PROGRAM_MENU}
|
808 |
* <li>{@link #START_MENU}
|
809 |
* <li>{@link #STARTUP}
|
810 |
* </ul>
|
811 |
*<br>
|
812 |
*
|
813 |
* @see #setLinkType
|
814 |
*/
|
815 |
public int getLinkType() |
816 |
{ |
817 |
return linkType;
|
818 |
} |
819 |
|
820 |
/*--------------------------------------------------------------------------*/
|
821 |
/**
|
822 |
* Sets the (ShellLink) user type for link
|
823 |
*
|
824 |
* @param type the type of user for the link.
|
825 |
*
|
826 |
* @see #CURRENT_USER
|
827 |
* @see #ALL_USERS
|
828 |
*
|
829 |
* @exception IllegalArgumentException if an an invalid type is passed
|
830 |
*/
|
831 |
public void setUserType (int type) throws IllegalArgumentException |
832 |
{ |
833 |
if ((type == CURRENT_USER) || (type == ALL_USERS))
|
834 |
{ |
835 |
userType = type; |
836 |
} |
837 |
else
|
838 |
{ |
839 |
throw (new IllegalArgumentException (type + " is not a recognized user type")); |
840 |
} |
841 |
} |
842 |
|
843 |
/*--------------------------------------------------------------------------*/
|
844 |
/**
|
845 |
* Returns the (ShellLink) user type for the link. Either {@link #CURRENT_USER} or
|
846 |
* {@link #ALL_USERS}
|
847 |
*
|
848 |
* @see #setUserType
|
849 |
*/
|
850 |
public int getUserType () |
851 |
{ |
852 |
return userType;
|
853 |
} |
854 |
|
855 |
/*--------------------------------------------------------------------------*/
|
856 |
/**
|
857 |
* Returns the path where the links of the selected type are stroed. This
|
858 |
* method is useful for discovering which program groups already exist.
|
859 |
*
|
860 |
* @param userType the type of user for the link path. One of {@link
|
861 |
* #CURRENT_USER} or {@link #ALL_USERS}
|
862 |
*
|
863 |
* @return the path to the type of link set for this instance.
|
864 |
*/
|
865 |
public String getLinkPath (int userType) |
866 |
{ |
867 |
if (userType == CURRENT_USER)
|
868 |
{ |
869 |
return (currentUserLinkPath);
|
870 |
} |
871 |
else
|
872 |
{ |
873 |
return (allUsersLinkPath);
|
874 |
} |
875 |
} |
876 |
|
877 |
/*--------------------------------------------------------------------------*/
|
878 |
/**
|
879 |
* Returns the command line that the link passes to the target.
|
880 |
*
|
881 |
* @return the command line
|
882 |
*
|
883 |
* @see #setArguments
|
884 |
*/
|
885 |
public String getArguments () |
886 |
{ |
887 |
return (arguments);
|
888 |
} |
889 |
|
890 |
/*--------------------------------------------------------------------------*/
|
891 |
/**
|
892 |
* Returns the description for the link.
|
893 |
*
|
894 |
* @return the description
|
895 |
*
|
896 |
* @see #setDescription
|
897 |
*/
|
898 |
public String getDescription () |
899 |
{ |
900 |
return (description);
|
901 |
} |
902 |
|
903 |
/*--------------------------------------------------------------------------*/
|
904 |
/**
|
905 |
* Retruns the hotkey that can be used to activate the link.
|
906 |
*
|
907 |
* @return the virtual keycode for the hotkey
|
908 |
*
|
909 |
* @see #setHotkey
|
910 |
*/
|
911 |
public int getHotkey () |
912 |
{ |
913 |
return (hotkey);
|
914 |
} |
915 |
|
916 |
/*--------------------------------------------------------------------------*/
|
917 |
/**
|
918 |
* Returns the path and file name of the file that contains the icon that
|
919 |
* is associated with the link.
|
920 |
*
|
921 |
* @return the path to the icon
|
922 |
*
|
923 |
* @see #setIconLocation
|
924 |
*/
|
925 |
public String getIconLocation () |
926 |
{ |
927 |
return (iconPath);
|
928 |
} |
929 |
|
930 |
/*--------------------------------------------------------------------------*/
|
931 |
/**
|
932 |
* Returns the index of the icon with the icon or resource file
|
933 |
*
|
934 |
* @return the index
|
935 |
*
|
936 |
* @see #setIconLocation
|
937 |
*/
|
938 |
public int getIconIndex () |
939 |
{ |
940 |
return (iconIndex);
|
941 |
} |
942 |
|
943 |
/*--------------------------------------------------------------------------*/
|
944 |
/**
|
945 |
* Retruns the absolute path of the link target
|
946 |
*
|
947 |
* @return the path
|
948 |
*
|
949 |
* @see #setTargetPath
|
950 |
*/
|
951 |
public String getTargetPath () |
952 |
{ |
953 |
return (targetPath);
|
954 |
} |
955 |
|
956 |
/*--------------------------------------------------------------------------*/
|
957 |
/**
|
958 |
* Returns the initial condition of the target window (HIDE, NORMAL,
|
959 |
* MINIMIZED, MAXIMIZED).
|
960 |
*
|
961 |
* @return the target show command
|
962 |
*
|
963 |
* @see #setShowCommand
|
964 |
*/
|
965 |
public int getShowCommand () |
966 |
{ |
967 |
return (showCommand);
|
968 |
} |
969 |
|
970 |
/*--------------------------------------------------------------------------*/
|
971 |
/**
|
972 |
* Retruns the working deirectory for the link target.
|
973 |
*
|
974 |
* @return the working directory
|
975 |
*
|
976 |
* @see #setWorkingDirectory
|
977 |
*/
|
978 |
public String getWorkingDirectory () |
979 |
{ |
980 |
return (workingDirectory);
|
981 |
} |
982 |
|
983 |
/*--------------------------------------------------------------------------*/
|
984 |
/**
|
985 |
* Returns the fully qualified file name under which the link is saved on
|
986 |
* disk. <b>Note:</b> this method returns valid results only if the instance
|
987 |
* was created from a file on disk or after a successful save operation.
|
988 |
*
|
989 |
* @return the fully qualified file name for the shell link
|
990 |
*/
|
991 |
public String getFileName () |
992 |
{ |
993 |
return (linkFileName);
|
994 |
} |
995 |
|
996 |
/*--------------------------------------------------------------------------*/
|
997 |
/**
|
998 |
* Returns the path of the directory where the link file is stored, if it
|
999 |
* was necessary during the previous save operation to create the directory.
|
1000 |
* This method returns <code>null</code> if no save operation was carried
|
1001 |
* out or there was no need to create a directory during the previous save
|
1002 |
* operation.
|
1003 |
*
|
1004 |
* @return the path of the directory where the link file is stored or
|
1005 |
* <code>null</code> if no save operation was carried out or
|
1006 |
* there was no need to create a directory during the previous
|
1007 |
* save operation.
|
1008 |
*/
|
1009 |
public String getDirectoryCreated () |
1010 |
{ |
1011 |
return (linkDirectory);
|
1012 |
} |
1013 |
|
1014 |
/*--------------------------------------------------------------------------*/
|
1015 |
/**
|
1016 |
* Returns the name shown in a menu or on the desktop for the link.
|
1017 |
*
|
1018 |
* @return the name
|
1019 |
*/
|
1020 |
public String getLinkName () |
1021 |
{ |
1022 |
return (linkName);
|
1023 |
} |
1024 |
|
1025 |
/*--------------------------------------------------------------------------*/
|
1026 |
/**
|
1027 |
* Returns the path for currentusersLink
|
1028 |
*
|
1029 |
* @return currentUsersLinkPath
|
1030 |
*/
|
1031 |
public String getcurrentUserLinkPath () |
1032 |
{ |
1033 |
return (currentUserLinkPath);
|
1034 |
} |
1035 |
|
1036 |
/*--------------------------------------------------------------------------*/
|
1037 |
/**
|
1038 |
* Returns the path for allusersLink
|
1039 |
*
|
1040 |
* @return allusersLinkPath
|
1041 |
*/
|
1042 |
public String getallUsersLinkPath () |
1043 |
{ |
1044 |
return (allUsersLinkPath);
|
1045 |
} |
1046 |
|
1047 |
/*--------------------------------------------------------------------------*/
|
1048 |
/**
|
1049 |
* Saves this link.
|
1050 |
*
|
1051 |
* @exception Exception if problems are encountered
|
1052 |
*/
|
1053 |
public void save () throws Exception |
1054 |
{ |
1055 |
// set all values on the native side
|
1056 |
set (); |
1057 |
|
1058 |
// make sure the target actually resolves
|
1059 |
int result = Resolve ();
|
1060 |
|
1061 |
if (result != SL_OK)
|
1062 |
{ |
1063 |
throw (new Exception ("cannot resolve target")); |
1064 |
} |
1065 |
|
1066 |
// make sure the directory exists
|
1067 |
File directory = new File (fullLinkPath (userType)); |
1068 |
|
1069 |
if (!directory.exists ())
|
1070 |
{ |
1071 |
directory.mkdirs (); |
1072 |
linkDirectory = directory.getPath (); |
1073 |
} |
1074 |
else
|
1075 |
{ |
1076 |
linkDirectory = "";
|
1077 |
} |
1078 |
|
1079 |
|
1080 |
// perform the save operation
|
1081 |
String saveTo = fullLinkName (userType);
|
1082 |
|
1083 |
result = saveLink (saveTo); |
1084 |
|
1085 |
if (result == SL_NO_IPERSIST)
|
1086 |
{ |
1087 |
throw (new Exception ("could not get handle for IPesist")); |
1088 |
} |
1089 |
else if (result == SL_NO_SAVE) |
1090 |
{ |
1091 |
throw (new Exception ("the save operation failed")); |
1092 |
} |
1093 |
|
1094 |
linkFileName = saveTo; |
1095 |
} |
1096 |
|
1097 |
/*--------------------------------------------------------------------------*/
|
1098 |
/**
|
1099 |
* Saves this link to any desired location.
|
1100 |
*
|
1101 |
* @param name the fully qualified file name for the link
|
1102 |
*
|
1103 |
* @exception IllegalArgumentException if the parameter was null
|
1104 |
* @exception Exception if the save operation could not be carried out
|
1105 |
*/
|
1106 |
public void save (String name) throws Exception |
1107 |
{ |
1108 |
if (name == null) |
1109 |
{ |
1110 |
throw (new IllegalArgumentException ("name was null")); |
1111 |
} |
1112 |
|
1113 |
// set all values on the native side
|
1114 |
set (); |
1115 |
|
1116 |
// make sure the target actually resolves
|
1117 |
if (Resolve () != SL_OK)
|
1118 |
{ |
1119 |
throw (new Exception ("cannot resolve target")); |
1120 |
} |
1121 |
|
1122 |
// make sure the directory exists
|
1123 |
File directory = new File (name.substring (0, name.lastIndexOf (File.separatorChar))); |
1124 |
if (!directory.exists ())
|
1125 |
{ |
1126 |
directory.mkdirs (); |
1127 |
linkDirectory = directory.getPath (); |
1128 |
} |
1129 |
else
|
1130 |
{ |
1131 |
linkDirectory = null;
|
1132 |
} |
1133 |
|
1134 |
// perform the save operation
|
1135 |
if (saveLink (name) != SL_OK)
|
1136 |
{ |
1137 |
throw (new Exception ("the save operation failed")); |
1138 |
} |
1139 |
|
1140 |
linkFileName = name; |
1141 |
} |
1142 |
|
1143 |
/*--------------------------------------------------------------------------*/
|
1144 |
/**
|
1145 |
* sets currentUsersLinkPath and allUsersLinkPath. If the path is empty,
|
1146 |
* resets userType to a valid userType for this type of link. If no
|
1147 |
* linkPaths are valid, an IllegalArgumentException is thrown.
|
1148 |
*
|
1149 |
* @throws IllegalArgumentException
|
1150 |
*/
|
1151 |
private void setAllLinkPaths() |
1152 |
throws IllegalArgumentException |
1153 |
{ |
1154 |
// sets currentUsersLinkPath and allUsersLinkPath
|
1155 |
GetFullLinkPath (CURRENT_USER, linkType); |
1156 |
GetFullLinkPath (ALL_USERS, linkType); |
1157 |
|
1158 |
// be sure userType is valid. Override initial choice if not.
|
1159 |
if ( userType == CURRENT_USER && currentUserLinkPath.length() == 0 ) |
1160 |
{ |
1161 |
userType = ALL_USERS; |
1162 |
} |
1163 |
else if ( userType == ALL_USERS && allUsersLinkPath.length() == 0 ) |
1164 |
{ |
1165 |
userType = CURRENT_USER; |
1166 |
} |
1167 |
|
1168 |
if ( allUsersLinkPath.length() == 0 && currentUserLinkPath.length() == 0 ) |
1169 |
{ |
1170 |
throw (new IllegalArgumentException ( |
1171 |
"linkType " + linkType + " is invalid.")); |
1172 |
} |
1173 |
} |
1174 |
|
1175 |
} |
1176 |
/*---------------------------------------------------------------------------*/
|
1177 |
|