/* * IzPack - Copyright 2001-2008 Julien Ponge, All Rights Reserved. * * http://izpack.org/ * http://izpack.codehaus.org/ * * Copyright 2002 Elmar Grom * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.izforge.izpack.util.os; import com.izforge.izpack.util.Debug; import com.izforge.izpack.util.StringTool; import java.io.File; import java.io.UnsupportedEncodingException; import java.util.Vector; /*---------------------------------------------------------------------------*/ /** * This is the Microsoft Windows specific implementation of <code>Shortcut</code>. * * @author Elmar Grom * @version 0.0.1 / 3/4/02 */ /*---------------------------------------------------------------------------*/ public class Win_Shortcut extends Shortcut { // ------------------------------------------------------------------------ // Constant Definitions // ------------------------------------------------------------------------ // ------------------------------------------------------------------------ // Variable Declarations // ------------------------------------------------------------------------ private ShellLink shortcut; private static String myClass = Win_Shortcut.class.getName() + ": "; private static final String CLASS = "Class: "; /** * SUPPORTED = true */ private static final boolean SUPPORTED = true; /*--------------------------------------------------------------------------*/ /** * This method initializes the object. It is used as a replacement for the constructor because * of the way it is instantiated through the <code>TargetFactory</code>. * * @param type the type or classification of the program group in which the link should exist. * The following types are recognized: <br> * <ul> * <li>{@link com.izforge.izpack.util.os.Shortcut#APPLICATIONS} * <li>{@link com.izforge.izpack.util.os.Shortcut#START_MENU} * <li>{@link com.izforge.izpack.util.os.Shortcut#DESKTOP} * <li>{@link com.izforge.izpack.util.os.Shortcut#START_UP} * </ul> * @param name the name of the shortcut. */ public void initialize(int type, String name) throws Exception { Debug.log(CLASS + myClass + ".initialize() '" + Integer.toString(type) + "', '" + name + "'"); switch (type) { case APPLICATIONS: { shortcut = new ShellLink(ShellLink.PROGRAM_MENU, name); break; } case START_MENU: { shortcut = new ShellLink(ShellLink.START_MENU, name); break; } case DESKTOP: { shortcut = new ShellLink(ShellLink.DESKTOP, name); break; } case START_UP: { shortcut = new ShellLink(ShellLink.STARTUP, name); break; } default: { shortcut = new ShellLink(ShellLink.PROGRAM_MENU, name); break; } } } /*--------------------------------------------------------------------------*/ /** * Returns the base path of the shortcut depending on type. The base path is the directory that * the short cut, (or its program group) will be created in. For instance, on Windows NT, a * shortcut with user-type ALL_USERS, and link-type DESKTOP might have the base path * "C:\Program Files\All Users\Desktop" * * @see #setLinkType(int) * @see #setUserType(int) * <p/> * translates from ShellLink-UserTypes to Shortcut-UserTypes. */ public String getBasePath() throws Exception { String result = shortcut.getLinkPath(shortcut.getUserType()); Debug.log(CLASS + myClass + ".getBasePath() '" + result + "'"); return result; } /** * Returns a list of currently existing program groups, based on the requested type. For example * if the type is <code>APPLICATIONS</code> then all the names of the program groups in the * Start Menu\Programs menu would be returned. * * @param userType the type of user for the program group set. (as Shortcut.utype) * @return a <code>Vector</code> of <code>String</code> objects that represent the names of * the existing program groups. It is theoretically possible that this list is empty. * @see #APPLICATIONS * @see #START_MENU */ public Vector<String> getProgramGroups(int userType) { int logentry = 0; Debug.log(CLASS + myClass + ".getProgramGroups()-" + logentry++ + " '" + Integer.toString(userType) + "'"); // ---------------------------------------------------- // translate the user type // ---------------------------------------------------- int type = ShellLink.CURRENT_USER; if (userType == ALL_USERS) { type = ShellLink.ALL_USERS; } else { type = ShellLink.CURRENT_USER; } // ---------------------------------------------------- // get a list of all files and directories that are // located at the link path. // ---------------------------------------------------- String linkPath = shortcut.getLinkPath(type); Debug.log(CLASS + myClass + ".getProgramGroups()-" + logentry++ + " '" + linkPath + "'"); // in case there is a problem obtaining a path return // an empty vector (there are no preexisting program // groups) if (linkPath == null) { return (new Vector<String>()); } File path = new File(linkPath); File[] file = path.listFiles(); // ---------------------------------------------------- // build a vector that contains only the names of // the directories. // ---------------------------------------------------- Vector<String> groups = new Vector<String>(); if (file != null) { for (File aFile : file) { String aFilename = aFile.getName(); if (aFile.isDirectory()) { Debug.log(CLASS + myClass + ".getProgramGroups()-" + logentry++ + " '" + aFilename + "'"); groups.add(aFilename); } else { Debug.log(CLASS + myClass + ".getProgramGroups()-" + logentry++ + " Skip (NoDirectory): '" + aFilename + "'"); } } } return (groups); } /*--------------------------------------------------------------------------*/ /** * Returns the fully qualified file name under which the link is saved on disk. <b>Note: </b> * this method returns valid results only if the instance was created from a file on disk or * after a successful save operation. * * @return the fully qualified file name for the shell link */ public String getFileName() { String aFilename = shortcut.getFileName(); Debug.log(CLASS + myClass + ".getFileName() '" + aFilename + "'"); return (aFilename); } /*--------------------------------------------------------------------------*/ /** * Returns the path of the directory where the link file is stored, if it was necessary during * the previous save operation to create the directory. This method returns <code>null</code> * if no save operation was carried out or there was no need to create a directory during the * previous save operation. * * @return the path of the directory where the link file is stored or <code>null</code> if no * save operation was carried out or there was no need to create a directory during the previous * save operation. */ public String getDirectoryCreated() { String directoryCreated = shortcut.getDirectoryCreated(); Debug.log(CLASS + myClass + ".getDirectoryCreated() '" + directoryCreated + "'"); return (directoryCreated); } /*--------------------------------------------------------------------------*/ /** * Returns <code>true</code> if the target OS supports current user and all users. * * @return <code>true</code> if the target OS supports current and all users. */ public boolean multipleUsers() { boolean result = false; // Win NT4 won't have PROGRAMS for CURRENT_USER. // Win 98 may not have 'Start Menu\Programs' for ALL_USERS String allUsers = shortcut.getallUsersLinkPath(); Debug.log(CLASS + myClass + ".multipleUsers()-1 '" + allUsers + "'"); String currentUsers = shortcut.getcurrentUserLinkPath(); Debug.log(CLASS + myClass + ".multipleUsers()-2 '" + currentUsers + "'"); if (allUsers == null || currentUsers == null) { result = false; } else { result = allUsers.length() > 0 && currentUsers.length() > 0; } Debug.log(CLASS + myClass + ".multipleUsers()-3 '" + result + "'"); return (result); } /*--------------------------------------------------------------------------*/ /** * Signals that this flavor of <code>{@link com.izforge.izpack.util.os.Shortcut}</code> * supports the creation of shortcuts. * * @return always <code>true</code> */ public boolean supported() { Debug.log(CLASS + myClass + ".supported() '" + SUPPORTED + "'"); return (SUPPORTED); } /*--------------------------------------------------------------------------*/ /** * Sets the command line arguments that will be passed to the target when the link is activated. * * @param arguments the command line arguments */ public void setArguments(String arguments) { Debug.log(CLASS + myClass + ".setArguments() '" + arguments + "'"); shortcut.setArguments(arguments); } /*--------------------------------------------------------------------------*/ /** * Sets the description string that is used to identify the link in a menu or on the desktop. * * @param description the descriptiojn string */ public void setDescription(String description) { Debug.log(CLASS + myClass + ".setDescription() '" + description + "'"); shortcut.setDescription(description); } /*--------------------------------------------------------------------------*/ /** * Sets the location of the icon that is shown for the shortcut on the desktop. * * @param path a fully qualified file name of a file that contains the icon. * @param index the index of the specific icon to use in the file. If there is only one icon in * the file, use an index of 0. */ public void setIconLocation(String path, int index) { Debug.log(CLASS + myClass + ".setIconLocation() '" + path + "', '" + Integer.toString(index) + "'"); shortcut.setIconLocation(path, index); } /*--------------------------------------------------------------------------*/ /** * returns icon Location * * @return iconLocation */ public String getIconLocation() { String result = shortcut.getIconLocation(); Debug.log(CLASS + myClass + ".getIconLocation() '" + result + "'"); return result; } /*--------------------------------------------------------------------------*/ /** * Sets the name of the program group this ShellLinbk should be placed in. * * @param groupName the name of the program group */ public void setProgramGroup(String groupName) { Debug.log(CLASS + myClass + ".setProgramGroup() '" + groupName + "'"); shortcut.setProgramGroup(groupName); } /*--------------------------------------------------------------------------*/ /** * Sets the show command that is passed to the target application when the link is activated. * The show command determines if the the window will be restored to the previous size, * minimized, maximized or visible at all. <br> * <br> * <b>Note: </b> <br> * Using <code>HIDE</code> will cause the target window not to show at all. There is not even * a button on the taskbar. This is a very useful setting when batch files are used to launch a * Java application as it will then appear to run just like any native Windows application. <br> * * @param show the show command. Valid settings are: <br> * <ul> * <li>{@link com.izforge.izpack.util.os.Shortcut#HIDE} * <li>{@link com.izforge.izpack.util.os.Shortcut#NORMAL} * <li>{@link com.izforge.izpack.util.os.Shortcut#MINIMIZED} * <li>{@link com.izforge.izpack.util.os.Shortcut#MAXIMIZED} * </ul> * @see #getShowCommand internally maps from Shortcut. to ShellLink. */ public void setShowCommand(int show) throws IllegalArgumentException { Debug.log(CLASS + myClass + ".setShowCommand() '" + Integer.toString(show) + "'"); switch (show) { case HIDE: { shortcut.setShowCommand(ShellLink.MINNOACTIVE); break; } case NORMAL: { shortcut.setShowCommand(ShellLink.NORMAL); break; } case MINIMIZED: { shortcut.setShowCommand(ShellLink.MINNOACTIVE); break; } case MAXIMIZED: { shortcut.setShowCommand(ShellLink.MAXIMIZED); break; } default: { throw (new IllegalArgumentException(show + "is not recognized as a show command")); } } } /* * returns current showCommand. internally maps from ShellLink. to Shortcut. * */ public int getShowCommand() { int showCommand = shortcut.getShowCommand(); Debug.log(CLASS + myClass + ".getShowCommand() '" + Integer.toString(showCommand) + "'"); switch (showCommand) { case ShellLink.NORMAL: showCommand = NORMAL; break; // both MINNOACTIVE and MINIMIZED map to Shortcut.MINIMIZED case ShellLink.MINNOACTIVE: case ShellLink.MINIMIZED: showCommand = MINIMIZED; break; case ShellLink.MAXIMIZED: showCommand = MAXIMIZED; break; default: break; } return showCommand; } /*--------------------------------------------------------------------------*/ /** * Sets the absolute path to the shortcut target. * * @param path the fully qualified file name of the target */ public void setTargetPath(String path) { Debug.log(CLASS + myClass + ".setTargetPath() '" + path + "'"); shortcut.setTargetPath(path); } /*--------------------------------------------------------------------------*/ /** * Sets the working directory for the link target. * * @param dir the working directory */ public void setWorkingDirectory(String dir) { Debug.log(CLASS + myClass + ".setWorkingDirectory() '" + dir + "'"); shortcut.setWorkingDirectory(dir); } /*--------------------------------------------------------------------------*/ /** * Gets the working directory for the link target. * * @return the working directory. */ public String getWorkingDirectory() { String result = shortcut.getWorkingDirectory(); Debug.log(CLASS + myClass + ".getWorkingDirectory() '" + result + "'"); return result; } /*--------------------------------------------------------------------------*/ /** * Sets the name shown in a menu or on the desktop for the link. * * @param name The name that the link should display on a menu or on the desktop. Do not include * a file extension. */ public void setLinkName(String name) { Debug.log(CLASS + myClass + ".setLinkName() '" + name + "'"); shortcut.setLinkName(name); } /*--------------------------------------------------------------------------*/ /** * Gets the type of link types are: <br> * <ul> * <li>{@link com.izforge.izpack.util.os.Shortcut#DESKTOP} * <li>{@link com.izforge.izpack.util.os.Shortcut#APPLICATIONS} * <li>{@link com.izforge.izpack.util.os.Shortcut#START_MENU} * <li>{@link com.izforge.izpack.util.os.Shortcut#START_UP} * </ul> * maps from ShellLink-types to Shortcut-types. */ public int getLinkType() { int typ = shortcut.getLinkType(); Debug.log(CLASS + myClass + ".getLinkType() '" + typ + "'"); switch (typ) { case ShellLink.DESKTOP: typ = DESKTOP; break; case ShellLink.PROGRAM_MENU: typ = APPLICATIONS; break; case ShellLink.START_MENU: typ = START_MENU; break; case ShellLink.STARTUP: typ = START_UP; break; default: break; } return typ; } /*--------------------------------------------------------------------------*/ /** * Sets the type of link * * @param type The type of link desired. The following values can be set: <br> * (note APPLICATION on Windows is 'Start Menu\Programs') APPLICATION is a Mac term. * <ul> * <li>{@link com.izforge.izpack.util.os.Shortcut#DESKTOP} * <li>{@link com.izforge.izpack.util.os.Shortcut#APPLICATIONS} * <li>{@link com.izforge.izpack.util.os.Shortcut#START_MENU} * <li>{@link com.izforge.izpack.util.os.Shortcut#START_UP} * </ul> * @throws IllegalArgumentException if an an invalid type is passed * @throws UnsupportedEncodingException */ public void setLinkType(int type) throws IllegalArgumentException, UnsupportedEncodingException { Debug.log(CLASS + myClass + ".setLinkType() '" + type + "'"); switch (type) { case DESKTOP: { shortcut.setLinkType(ShellLink.DESKTOP); break; } case APPLICATIONS: { shortcut.setLinkType(ShellLink.PROGRAM_MENU); break; } case START_MENU: { shortcut.setLinkType(ShellLink.START_MENU); break; } case START_UP: { shortcut.setLinkType(ShellLink.STARTUP); break; } default: { throw (new IllegalArgumentException(type + "is not recognized as a valid link type")); } } } /*--------------------------------------------------------------------------*/ /** * Gets the user type for the link * * @return userType * @see #CURRENT_USER * @see #ALL_USERS */ public int getUserType() { int utype = shortcut.getUserType(); Debug.log(CLASS + myClass + ".getUserType() '" + utype + "'"); switch (utype) { case ShellLink.ALL_USERS: utype = ALL_USERS; break; case ShellLink.CURRENT_USER: utype = CURRENT_USER; break; } return utype; } /*--------------------------------------------------------------------------*/ /** * Sets the user type for the link * * @param type the type of user for the link. * @see Shortcut#CURRENT_USER * @see Shortcut#ALL_USERS * <p/> * if the linkPath for that type is empty, refuse to set. */ /*--------------------------------------------------------------------------*/ public void setUserType(int type) { Debug.log(CLASS + myClass + ".setUserType() '" + type + "'"); if (type == CURRENT_USER) { if (shortcut.getcurrentUserLinkPath().length() > 0) { shortcut.setUserType(ShellLink.CURRENT_USER); } } else if (type == ALL_USERS) { if (shortcut.getallUsersLinkPath().length() > 0) { shortcut.setUserType(ShellLink.ALL_USERS); } } } /*--------------------------------------------------------------------------*/ /** * Saves this link. * * @throws Exception if problems are encountered */ public void save() throws Exception { shortcut.save(); } /*--------------------------------------------------------------------------*/ /** * Gets the link hotKey * * @return int hotKey */ public int getHotkey() { int result = shortcut.getHotkey(); Debug.log(CLASS + myClass + ".getHotkey() '" + result + "'"); return result; } /*--------------------------------------------------------------------------*/ /** * Sets the link hotKey * * @param hotkey incoming 2 byte hotkey is: high byte modifier: SHIFT = 0x01 CONTROL= 0x02 ALT = 0x04 EXT = * 0x08 * <p/> * lower byte contains ascii letter. ie 0x0278 represents CTRL+x 0x068a represents CTRL+ALT+z */ public void setHotkey(int hotkey) { Debug.log(CLASS + myClass + ".setHotkey() '" + hotkey + "'"); shortcut.setHotkey(hotkey); } /** * Gets the Folders where to place the program-groups and their shortcuts, for the given * usertype. * * @see com.izforge.izpack.util.os.Shortcut#getProgramsFolder(int) */ public String getProgramsFolder(int current_user) { /** CURRENT_USER = 0; the constant to use for selecting the current user. */ int USER = 0; if (current_user == Shortcut.CURRENT_USER) { USER = ShellLink.CURRENT_USER; } else if (current_user == Shortcut.ALL_USERS) { USER = ShellLink.ALL_USERS; } String result = null; try { result = new String(shortcut.getLinkPath(USER).getBytes(StringTool.getPlatformEncoding()), StringTool.getPlatformEncoding()); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } Debug.log(CLASS + myClass + ".getProgramsFolder() '" + current_user + "', '" + result + "'"); return result; } } /*---------------------------------------------------------------------------*/