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 | 15280 | rgaitan | /*
|
---|---|---|---|
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 | /*---------------------------------------------------------------------------*/
|