Now that you know the basic steps involved in creating a shortcut using WSH, let's look at how to use the WshShortcut object and other objects to create shortcuts in one of the folders predefined by Windows, such as the Desktop, the Start menu, and so on, which are collectively known as special folders.
The CreateShortcut method requires that you specify the path to the target folder, such as the folder for the Desktop or the Start menu. But here you run into a problem: the exact location of a special folder isn't obvious.
Because the Windows folder (in Windows 95 and Windows 98) has subfolders called Start Menu and Desktop for all Start and Desktop menu items, you might think that you can simply expand the environment variable WINDIR and extract the path to the subfolder you need. But if multiuser settings are enabled on Windows 95 or Windows 98, the Windows shell creates user-specific folders in the \Profiles subfolder, which itself has subfolders for the individual user's Desktop, Start menu, and so on.
In addition, programs such as the Tweak UI utility and even Microsoft Internet Explorer let you change the location of a special folder, and Windows 2000 keeps some special folders in different locations.
Fortunately, there's a way to find special folders. You can use the SpecialFolders property of the WshShell object. This property returns a WshSpecialFolders object containing a collection with the paths of all special folders. Using this collection, you can get the path of any folder for which you want to create a shortcut on the Desktop or the Start menu.
Table 10-1 shows the special folder names the WshSpecialFolders object uses, all of which you'll find on Microsoft Windows NT 4 and Windows 2000.
Table 10-1 Special Folders in Windows
Folder Name(s) | Description |
---|---|
AllUsersDesktop AllUsersStartMenu AllUsersPrograms AllUsersStartup |
Store data for all users. Some of the subfolders are specific to Windows NT and Windows 2000. Some are also found in Windows 98. |
Desktop | Defines all user-defined shortcuts for the Desktop of the current user. |
Favorites | Points to the Favorites menu. |
Fonts | Points to the folder containing all installed fonts (files and shortcut files to font files in other folders). |
MyDocuments | Points to the user-specific folder named My Documents. |
NetHood | An empty folder used as a placeholder for the network environment. |
PrintHood | An empty folder used for printer mapping in the network. |
Programs | Points to the subfolder for the user-defined entries in the Programs command on the Start menu. |
Recent | Points to the Recent Files folder. |
SendTo | Points to the SendTo folder. |
StartMenu | Points to the user-defined Start Menu folder. |
Startup | Points to the user-defined Startup folder. |
Templates | Points to the ShellNew folder, which contains the templates for new files. |
You use these names to get the location of a special folder from the WshSpecialFolders collection. The actual folder name returned by WshSpecialFolders might differ from the one in Table 10-1.
NOTE
WshShell.SpecialFolders(strFolderName) returns the value Null if the folder requested in strFolderName doesn't exist. For example, Windows 95 doesn't have an AllUsers\Desktop folder; for strFolderName = AllUsersDesktop, the SpecialFolders property returns Null.
The following sample displays a dialog box that lists all special folders on the local machine. As you can see in Figure 10-2, the machines in this sample keep special folders in different locations. Also, the folder names depend on the localized version of Windows being used. The dialog box on the left belongs to a German Windows 98 version, and the dialog box on the right is from Windows 2000 (logged in as an administrator). The Windows 2000 dialog box shows two special folders for the Desktop and the Start menu.
Figure 10-2 Paths to special folders in Windows 98 (left) and Windows 2000 (right)
To access the SpecialFolders property, you need the WshShell object, which you create by using the following VBScript statement:
Set WshShell = WScript.CreateObject("WScript.Shell") |
The CreateObject method instantiates a copy of the WshShell object and assigns a reference to this object to the WshShell object variable. You can use this object variable to retrieve the SpecialFolders property, which contains a WshSpecialFolders collection.
The Count and length properties of the WshSpecialFolders object both contain the number of entries in the collection.
NOTE
The WshSpecialFolders object offers both the Count and length properties for compatibility with VBScript and JScript. Commonly, Count is used in VBScript and length in JScript.
To process all elements in a collection, you can use a For Each…In loop in VBScript:
For Each i In WshShell.SpecialFolders WScript.Echo i Next |
This loop displays all special folders in the collection in separate dialog boxes. The variable i contains an item (pathname) retrieved from the WshSpecialFolders collection.
Listing 10-3 retrieves the paths to all special folders and displays them in a dialog box.
Listing 10-3 SpecialFolder.vbs
'***************************************************** ' File: SpecialFolder.vbs (WSH sample in VBScript) ' Author: (c) G. Born ' ' Using the SpecialFolders property of the WshShell ' object to list all special folders in a dialog box '***************************************************** Option Explicit Dim Text, Title, i Dim WshShell ' Object variable Text = "The following special folders have been found:" & _ vbCrLf & vbCrLf Title = "WSH sample - by G. Born" ' Create WshShell object, which we'll use to access the ' WshSpecialFolders object. Set WshShell = WScript.CreateObject("WScript.Shell") ' Get the paths to the special folders. For Each i In WshShell.SpecialFolders Text = Text & i & vbCrLf Next WScript.Echo Text ' Show result. '*** End |
Listing 10-4 shows the JScript implementation.
Listing 10-4 SpecialFolder.js
//**************************************************** // File: SpecialFolder.js (WSH sample in JScript) // Author: (c) G. Born // // Using the SpecialFolders property of the WshShell // object to list all special folders in a dialog box //**************************************************** var Text = "The following special folders have been found:\n\n"; var Title = "WSH sample - by G. Born"; // Create WshShell object, which we'll use to access the // WshSpecialFolders object. var WshShell = WScript.CreateObject("WScript.Shell"); // Show paths to special folders. var objAdr = WshShell.SpecialFolders /// Attention: The next for loop doesn't work /// for (var i in objAdr). /// { /// WScript.Echo ("*" + i + "\n"); /// } /// Therefore, we'll use for (var i = 0; i < objAdr.length; i++) { Text = Text + objAdr(i) + "\n"; } WScript.Echo(Text); // Show result. //*** End |
You can also use the SpecialFolders property to retrieve the path of a specific special folder. The WshSpecialFolders collection not only gets the path but also returns the localized folder names, so your script is independent from localized Windows versions.
These two VBScript statements display the path to the Desktop folder:
Set WshShell = WScript.CreateObject("WScript.Shell") WScript.Echo "Desktop: " & WshShell.SpecialFolders("Desktop") |
The first line creates a WshShell object instance, which exposes the SpecialFolders property. The second line accesses an item in the WshSpecialFolders collection through the SpecialFolders property. Our sample uses the folder name Desktop as an index, which causes the WshSpecialFolders object to return just that one item from the collection. Because Item is the default property of the WshSpecialFolders object, you don't need to specify the Item property name to get the path to the Desktop folder.
The VBScript program in Listing 10-5 uses this approach to retrieve a few special folders and show the results in a dialog box, as shown in Figure 10-3.
Listing 10-5 SpecialFolder1.vbs
'****************************************************** ' File: SpecialFolder1.vbs (WSH sample in VBScript) ' Author: (c) G. Born ' ' Using the SpecialFolders property of the WshShell ' object to list specific special folders in a ' dialog box '****************************************************** Option Explicit Dim Text, Title Dim WshShell Text = "The following special folders have been found:" & _ vbCrLf & vbCrLf Title = "WSH sample - by G. Born" ' Create the WshShell object, which we'll use to access the ' WshSpecialFolders object. Set WshShell = WScript.CreateObject("WScript.Shell") ' Get the paths to the special folders. Text = Text & "Desktop: " & _ WshShell.SpecialFolders("Desktop") & vbCrLf Text = Text & "Startmenu: " & _ WshShell.SpecialFolders("Startmenu") & vbCrLf Text = Text & "Startup: " & _ WshShell.SpecialFolders("Startup") & vbCrLf Text = Text & "MyDocuments: " & _ WshShell.SpecialFolders("MyDocuments") & vbCrLf Text = Text & "Templates: " & _ WshShell.SpecialFolders("Templates") & vbCrLf WScript.Echo Text ' Show results. '*** End |
Figure 10-3 The paths to some special folders
The JScript version is shown in Listing 10-6.
Listing 10-6 SpecialFolder1.js
//**************************************************** // File: SpecialFolder1.js (WSH sample in JScript) // Author: (c) G. Born // // Using the SpecialFolder property of the WshShell // object to list specific special folders in a // dialog box //**************************************************** var Text = "The following special folders have been found:\n\n"; var Title = "WSH sample - by G. Born"; // Create WshShell object, which we'll use to access the // WshSpecialFolders object. var WshShell = WScript.CreateObject("WScript.Shell"); // Get the paths to the special folders. Text = Text + "Desktop: " + WshShell.SpecialFolders("Desktop") + "\n"; Text = Text + "Startmenu: " + WshShell.SpecialFolders("Startmenu") + "\n"; Text = Text + "Startup: " + WshShell.SpecialFolders("Startup") + "\n"; Text = Text + "MyDocuments: " + WshShell.SpecialFolders("MyDocuments") + "\n"; Text = Text + "Templates: " + WshShell.SpecialFolders("Templates") + "\n"; WScript.Echo(Text); // Result //*** End |
Now let's create a shortcut on the Desktop. Our sample will create a shortcut to the Windows Editor. The sample will display a dialog box that asks the user whether to create this shortcut. If the user clicks Yes, the script takes these steps:
The following VBScript code sequence creates a reference to the WshShell object, retrieves the path to the Desktop folder, sets the title of the shortcut file, and calls the CreateShortcut method:
Set WshShell = WScript.CreateObject("WScript.Shell") DesktopPath = WshShell.SpecialFolders("Desktop") Lnk_Title = "\Editor.lnk" Set Shortcut = WshShell.CreateShortcut(DesktopPath & Lnk_Title) |
The DesktopPath variable contains the path to the Desktop folder, and Lnk_Title contains the name of the shortcut .lnk file. Next, you define a few properties of the WshShortcut object. You use the TargetPath property of the new WshShortcut object to set the command to be executed after a double-click on the shortcut icon:
Shortcut.TargetPath = _ WshShell.ExpandEnvironmentStrings("%WINDIR%\Notepad.exe") |
The ExpandEnvironmentStrings method expands the content of the environment variable %WINDIR%. In other words, the method retrieves the Windows folder that contains the Windows Editor, Notepad.exe. Once you append the string " \Notepad.exe " to this folder, the executable command is complete.
You now specify the working directory for the shortcut. Applications use this directory to store temporary files and other files.
Shortcut.WorkingDirectory = _ WshShell.ExpandEnvironmentStrings("%WINDIR%\Temp") |
Our sample sets this property to the Windows subfolder \Temp because the editor doesn't need a working directory. The WindowStyle property determines the mode in which the application window is shown after the shortcut is activated:
Shortcut.WindowStyle = 1 |
This property can have three possible values:
These styles are applicable only if the application window was terminated in Normal mode in the previous session.
The IconLocation property defines the link to the icon for the shortcut:
Shortcut.IconLocation = _ WshShell.ExpandEnvironmentStrings("%WINDIR%\Notepad.exe, 0") |
The command uses the first icon in Notepad.exe as the shortcut icon.
NOTE
In Windows, EXE and DLL files can contain one or more icons, which are counted from 0. Alternatively, you can use icon libraries such as Moricons.dll and Shell32.dll in the Windows folder or in the \System subfolder. Keep in mind, however, that the location of those files depends on the operating system. In Windows 2000, the files are in the \System32 subfolder, and in Windows 95 and Windows 98 they're in the Windows folder and the \System subfolder. You can also assign the path to a .bmp or .ico file to the IconLocation property.
Once you set the properties, you can use the Save method to create the shortcut file. The full VBScript implementation is shown in Listing 10-7.
Listing 10-7 Shortcut1.vbs
'************************************************* ' File: Shortcut1.vbs (WSH sample in VBScript) ' Author: (c) G. Born ' ' Creating a shortcut to the Windows Editor on ' the Desktop '************************************************* Option Explicit Dim Text, Title, Lnk_Title Dim WshShell ' Object variable Dim status, Ready_txt Dim Shortcut, DesktopPath Ready_txt = "Shortcut to the Windows Editor on the Desktop" Text = "Creates a shortcut to the Windows Editor on the Desktop" Title = "WSH sample - by G. Born" ' Ask the user whether to create shortcut. status = MsgBox(Text, _ vbOKCancel + vbInformation, _ Title) If (status <> vbOK) Then WScript.Quit 1 ' Cancel selected. End If ' Create a new WshShell object, which we'll need for ' the WshSpecialFolders object. Set WshShell = WScript.CreateObject("WScript.Shell") ' Get path to the Desktop folder using the ' WshSpecialFolders object. DesktopPath = WshShell.SpecialFolders("Desktop") ' We know the path to the Desktop folder, so we'll use the ' CreateShortcut method to create the shortcut. Lnk_Title = "\Editor.lnk" Set Shortcut = WshShell.CreateShortcut(DesktopPath & Lnk_Title) ' Set shortcut properties. ' Target folder Shortcut.TargetPath = _ WshShell.ExpandEnvironmentStrings("%WINDIR%\Notepad.exe") ' Working directory Shortcut.WorkingDirectory = _ WshShell.ExpandEnvironmentStrings("%WINDIR%") ' Windows style 1 = normal, 3 = maximized, 7 = minimized Shortcut.WindowStyle = 1 ' Shortcut icon Shortcut.IconLocation = _ WshShell.ExpandEnvironmentStrings("%WINDIR%\\Notepad.exe, 0") Shortcut.Save ' Create shortcut file. WScript.Echo Ready_txt ' Ready message '*** End |
The JScript version is shown in Listing 10-8.
Listing 10-8 Shortcut1.js
//************************************************ // File: Shortcut1.js (WSH sample in JScript) // Author: (c) G. Born // // Creating a shortcut to the Windows Editor on // the Desktop //************************************************ var vbOKCancel = 1; // Define variables. var vbInformation = 64; var vbCancel = 2; var L_Welcome_MsgBox_Message_Text = "Creates a shortcut to the Windows Editor on the Desktop"; var L_Welcome_MsgBox_Title_Text = "WSH sample - by G. Born"; Welcome(); // Show welcome dialog box. // Method for creating a shortcut var WshShell = WScript.CreateObject("WScript.Shell"); // Get Desktop path using the WshSpecialFolders object. var DesktopPath = WshShell.SpecialFolders("Desktop"); // Create shortcut file on Desktop. var Shortcut = WshShell.CreateShortcut(DesktopPath + "\\Editor.lnk"); // Set object properties; %WINDIR% specifies the Windows folder. Shortcut.TargetPath = WshShell.ExpandEnvironmentStrings("%WINDIR%\\Notepad.exe"); Shortcut.WorkingDirectory = WshShell.ExpandEnvironmentStrings("%WINDIR%"); Shortcut.WindowStyle = 1; // Windows style normal Shortcut.IconLocation = WshShell.ExpandEnvironmentStrings("%WINDIR%\\Notepad.exe, 0"); Shortcut.Save(); // Store shortcut. WScript.Echo("Shortcut to the Windows Editor on the Desktop"); /////////////////////////////////////////////////////////// // // Welcome // function Welcome() { var WshShell = WScript.CreateObject("WScript.Shell"); var intDoIt; intDoIt = WshShell.Popup(L_Welcome_MsgBox_Message_Text, 0, L_Welcome_MsgBox_Title_Text, vbOKCancel + vbInformation ); if (intDoIt == vbCancel) { WScript.Quit(); } } //*** End |
Now let's create a shortcut on the Start menu. We'll create a new entry (also known as a group) named Born on the Start menu's Programs group. We'll use the new group to create a shortcut to Notepad.
NOTE
Creating a shortcut in a new group instead of using an existing entry such as Accessories requires a few additional steps. You must verify that the new group exists before you can apply the CreateShortcut method.
In principle, this task shouldn't be more complicated than the previous samples. You simply use the CreateShortcut method and submit the path to the destination folder and the shortcut filename as a parameter. You can use the filename Editor.lnk for the shortcut file. All that's missing is the path to the destination folder for the shortcut file. The path must point to the Start menu group \Programs\Born.
You can use the SpecialFolders property of the WshShell object to retrieve the path to Startmenu\Programs. But because this sample will use the Born group for the shortcut, the path must be extended to include this subfolder name.
WARNING
When you create a shortcut, you can't apply the Save method of the WshShortcut object if the target path doesn't exist. You'll get a run-time error.
How do you make sure the destination folder exists, and how do you create a folder for the new program group? You could call the Run method and create a new folder using something like the MS-DOS MD command. But here's a better approach (in VBScript):
Sub MakePath(pathx) On Error Resume Next ' Create a folder if one doesn't exist. Dim fso, f Set fso = CreateObject("Scripting.FileSystemObject") Set f = fso.CreateFolder(pathx) Set fso = Nothing Set f = Nothing On Error GoTo 0 End Sub |
You must call this procedure with a parameter containing the whole path to the folder, as in "C:\Windows\Born\". If a run-time error occurs, the On Error Resume Next statement causes the program to continue with the next statement.
NOTE
For details on using the FileSystemObject object, see Chapter 12.
A FileSystemObject object is then created. The methods of this object allow you to handle files and folders. The CreateFolder method creates the folder passed as an argument. If the folder already exists, a run-time error occurs and the On Error Resume Next statement forces the script to continue with the next statement. Nothing changes in the file system. If the folder doesn't exist, no run-time error is generated and the new folder is created.
You call the MakePath procedure with the path to the subfolder Born as an argument, and then you apply the CreateShortcut method:
MakePath Path Set Shortcut = WshShell.CreateShortcut(Path & "Editor.lnk") |
Once you have the WshShortcut object, you can set its properties. Notepad is in the Windows folder in the file Notepad.exe, so you can get the path to this file as shown in the previous examples.
In addition to the shortcut object properties you learned about earlier in the chapter, you can set the Hotkey property, which defines a hot key for executing a shortcut:
Shortcut.Hotkey = "Alt+Ctrl+E" |
In this code, the key combination Alt+Ctrl+E invokes Notepad.
IMPORTANT
You can use hot keys only for shortcuts in the Desktop or Start Menu folder. Windows processes those folders if a hot key is detected. You must make sure that the key combination you specify for the hot key isn't already used for other purposes. Otherwise, the hot key won't work or will affect other applications.
If you call the Save method of the WshShortcut object, the shortcut is created on the Start menu. You can verify the existence of this shortcut by opening the Start menu. The branch Programs/Born should contain a new entry for the Windows Editor. The VBScript implementation is shown in Listing 10-9.
Listing 10-9 Startmenu.vbs
'************************************************* ' File: Startmenu.vbs (WSH sample in VBScript) ' Author: (c) G. Born ' ' Creating a shortcut to Notepad in the ' Start menu group Born '************************************************* Option Explicit Dim Text, Title Dim WshShell ' Object variable Dim status, Ready_txt Dim Shortcut, Path Ready_txt = "Shortcut created" Text = _ "Creates a shortcut to Notepad on the Start menu (Group ""Born"")" Title = "WSH sample - by G. Born" ' Ask user whether to create shortcut. status = MsgBox(Text, _ vbOKCancel + vbInformation, _ Title) If (status <> vbOK) Then WScript.Quit 1 ' Cancel selected. End If ' Create WshShell object, which is needed for the ' WshSpecialFolders object. Set WshShell = WScript.CreateObject("WScript.Shell") ' Get path to the folder Startmenu/Programs using ' the WshSpecialFolders object. Path = WSHShell.SpecialFolders("Programs") ' Important: Entry goes into Programs\Born. Path = Path & "\Born\" ' Check whether path exists; if not, create group. MakePath Path ' We know the path to the Start menu; create shortcut using ' the CreateShortcut method. Set Shortcut = WshShell.CreateShortcut(Path & "Editor.lnk") ' Set shortcut properties. ' Target path Shortcut.TargetPath = _ WshShell.ExpandEnvironmentStrings("%WINDIR%\Notepad.exe") ' Working directory Shortcut.WorkingDirectory = _ WshShell.ExpandEnvironmentStrings("%WINDIR%") ' Windows style 1 = normal, 3 = maximized, 7 = minimized Shortcut.WindowStyle = 1 ' Shortcut icon Shortcut.IconLocation = _ WshShell.ExpandEnvironmentStrings("%WINDIR%\Notepad.exe, 0") ' Hot key for shortcut Shortcut.Hotkey = "Alt+CtrL+E" Shortcut.Save ' Create shortcut. WScript.Echo Ready_txt ' Show ready message. Sub MakePath(pathx) On Error Resume Next ' Create folder if it doesn't exist. Dim fso, f Set fso = CreateObject("Scripting.FileSystemObject") Set f = fso.CreateFolder(pathx) Set fso = Nothing Set f = Nothing On Error GoTo 0 End Sub '*** End |
The JScript version is shown in Listing 10-10. Within the function MakePath, I used the FolderExists method (discussed in Chapter 12) to check whether the folder exists. An alternative might be to use the try…catch statement in JScript (available since version 5.0) to catch run-time errors (similar to On Error Resume Next in VBScript).
Listing 10-10 Startmenu.js
//************************************************ // File: Startmenu.js (WSH sample in JScript) // Author: (c) G. Born // // Creating a shortcut to Notepad in the // Start menu group Born //************************************************ var vbOKCancel = 1; // Declare variables. var vbInformation = 64; var vbCancel = 2; var L_Welcome_MsgBox_Message_Text = "Creates a shortcut on the Start menu"; var L_Welcome_MsgBox_Title_Text = "WSH sample - by G. Born"; Welcome(); // Show welcome dialog box. // Get object with method for creating shortcut. var WshShell = WScript.CreateObject("WScript.Shell"); // Get path to the folder Startmenu/Programs using // the WshSpecialFolders object. var Path = WshShell.SpecialFolders("Programs"); // Important: Entry goes into Programs\Born. Path = Path + "\\Born\\"; // Test whether path exists; if not, create group. MakePath(Path); // We know the path to the Start menu; use the // CreateShortcut method to create the shortcut. var Shortcut = WshShell.CreateShortcut(Path + "Editor.lnk"); // Set shortcut properties; first comes the target path. Shortcut.TargetPath = WshShell.ExpandEnvironmentStrings("%WINDIR%\\Notepad.exe"); // Working directory Shortcut.WorkingDirectory = WshShell.ExpandEnvironmentStrings("%WINDIR%"); // Windows style 1 = normal, 3 = maximized, 7 = minimized Shortcut.WindowStyle = 1; // Shortcut icon Shortcut.IconLocation = WshShell.ExpandEnvironmentStrings("%WINDIR%\\Notepad.exe, 0"); // Hot key for shortcut Shortcut.Hotkey = "Alt+Ctrl+E"; Shortcut.Save(); // Create shortcut file. WScript.Echo("Shortcut file created"); ////////////////////////////////////////////////////////// // // Welcome // function Welcome() { var WshShell = WScript.CreateObject("WScript.Shell"); var intDoIt; intDoIt = WshShell.Popup(L_Welcome_MsgBox_Message_Text, 0, L_Welcome_MsgBox_Title_Text, vbOKCancel + vbInformation ); if (intDoIt == vbCancel) { WScript.Quit(); } } function MakePath(pathx) { // Create folder if it doesn't exist. var fso = new ActiveXObject("Scripting.FileSystemObject") if (!fso.FolderExists(pathx)) { var f = fso.CreateFolder(pathx); f = null; } fso = null; } //*** End |
You can use similar techniques to create shortcuts in other special folders (such as My Documents or Favorites). You simply use the WshShell.SpecialFolders property to get the path to the special folder.
TIP
If you want to create a shortcut on the Start menu in Windows NT or Windows 2000, you can do so for the current user, for a group of users, or for all users. You can modify the preceding script so that it retrieves the location of the current user's Start Menu special folder and add the shortcut there. To create a shortcut for a group of users, you start by retrieving the location of the current user's Start Menu and then moving two levels up in the folder hierarchy and enumerating all subfolders. Each subfolder belongs to a user account. You can retrieve the appropriate user's Start Menu folder and update the shortcut to ensure that the Start menu of selected users is updated. If you follow the sample above but use the All Users\Start Menu folder as a target, all users will see the shortcut on their Start menu.
If you manually open the property sheet of a shortcut, you can append several options to the Target text box. For example, the command C:\Windows\Notepad.exe C:\Text\Born.txt launches Notepad and loads Born.txt into it.
To append additional arguments to the shortcut command, you use the Arguments property. This property has nothing to do with the Arguments property exposed from the WScript object. Rather, it is a property of the WshShortcut object. The following sample creates a shortcut to Notepad in the Start menu's Programs/Born group. If the user chooses this Start menu command, the source code of the script is loaded. The shortcut must therefore contain the path and the script filename as extra arguments.
You can specify argument values for the shortcut object by using the Arguments property:
Shortcut.Arguments = WScript.ScriptFullName |
This code assigns the name of the script file to the Arguments property. The Start menu entry Programs/Born/... created from the script file invokes Notepad and loads the script's source code. The Save method creates the shortcut filename from the Shortcut object and appends the Arguments property to the shortcut command.
The VBScript code in Listing 10-11 creates a shortcut to Notepad on the Start menu and includes the name of the script file in the command.
Listing 10-11 Startmenu1.vbs
'************************************************** ' File: Startmenu1.vbs (WSH sample in VBScript) ' Author: (c) G. Born ' ' Creating a shortcut to Notepad in the ' Start menu group Born '************************************************** Option Explicit Dim Text, Title Dim WshShell ' Object variable Dim status, Ready_txt Dim Shortcut, Path Ready_txt = "Shortcut created" Text = "Creates a shortcut to Notepad in the Start menu group Born" Title = "WSH sample - by G. Born" ' Ask user whether to create shortcut. status = MsgBox(Text, _ vbOKCancel + vbInformation, _ Title) If (status <> vbOK) Then WScript.Quit 1 ' Cancel selected. End If ' Create WshShell object, which is needed for the ' WshSpecialFolders object. Set WshShell = WScript.CreateObject("WScript.Shell") ' Get path to the Start Menu/Programs folder using ' the WshSpecialFolders object. Path = WshShell.SpecialFolders("Programs") ' Important: entry goes into Programs\Born. Path = Path & "\Born\" ' Check whether path exists; if not, create group. MakePath Path ' We know the path to the Start menu. Create shortcut using the ' CreateShortcut method. Set Shortcut = WshShell.CreateShortcut(Path & "Editor.lnk") ' Set shortcut properties. ' Target path Shortcut.TargetPath = _ WshShell.ExpandEnvironmentStrings("%WINDIR%\Notepad.exe") ' Set arguments for program execution. ' Load the script file into Notepad. Shortcut.Arguments = WScript.ScriptFullName Shortcut.WorkingDirectory = _ WshShell.ExpandEnvironmentStrings("%WINDIR%") ' Windows style 1 = normal, 3 = maximized, 7 = minimized Shortcut.WindowStyle = 1 ' Shortcut icon Shortcut.IconLocation = _ WshShell.ExpandEnvironmentStrings("%WINDIR%\Notepad.exe, 0") ' Hot key for shortcut Shortcut.Hotkey = "Alt+CtrL+E" Shortcut.Save ' Create shortcut. WScript.Echo Ready_txt ' Show ready message. Sub MakePath(pathx) On Error Resume Next ' Create folder if it doesn't exist. Dim fso, f Set fso = CreateObject("Scripting.FileSystemObject") Set f = fso.CreateFolder(pathx) Set fso = Nothing Set f = Nothing On Error GoTo 0 End Sub '*** End |
TIP
The Save method stores the properties set in the script into the shortcut .lnk file. You need not set all Shortcut properties in the script. Any property not defined in the script stays unchanged in the .lnk file. You can test this by executing Startmenu1.vbs and then Startmenu.vbs. Both script programs create one shortcut file. The second program simply updates the existing file because Startmenu.vbs doesn't set the Arguments property. If you open the Start menu and choose the command for Born\Editor, Notepad is launched and Startmenu1.vbs is loaded. Obviously, the old property set in Startmenu1.vbs already exists. To prevent this behavior, you must set the property explicitly to an empty string.
The JScript implementation is shown in Listing 10-12.
Listing 10-12 Startmenu1.js
//************************************************ // File: Startmenu1.js (WSH sample in JScript) // Author: (c) G. Born // // Creating a shortcut to Notepad in the // Start menu group Born //************************************************ var vbOKCancel = 1; // Declare variables. var vbInformation = 64; var vbCancel = 2; var L_Welcome_MsgBox_Message_Text = "Creates a shortcut on the Start menu"; var L_Welcome_MsgBox_Title_Text = "WSH sample - by G. Born"; Welcome(); // Show welcome dialog box. // Get object with method for creating shortcut. var WshShell = WScript.CreateObject("WScript.Shell"); // Get path to the Start Menu/Programs folder using // the WshSpecialFolders object. var Path = WshShell.SpecialFolders("Programs"); // Important: entry goes into Programs\Born. Path = Path + "\\Born\\"; // Test whether path exists; if not, create group. MakePath(Path); // We have the path to the Start menu; use the // CreateShortcut method to create the shortcut. var Shortcut = WshShell.CreateShortcut(Path + "Editor.lnk"); // Set shortcut properties; first, the target path. Shortcut.TargetPath = WshShell.ExpandEnvironmentStrings("%WINDIR%\\Notepad.exe"); // Here are the arguments for the script. // Load the script file into Notepad. Shortcut.Arguments = WScript.ScriptFullName; // Working directory Shortcut.WorkingDirectory = WshShell.ExpandEnvironmentStrings("%WINDIR%"); // Windows style 1 = normal, 3 = maximized, 7 = minimized Shortcut.WindowStyle = 1; // Shortcut icon Shortcut.IconLocation = WshShell.ExpandEnvironmentStrings("%WINDIR%\\Notepad.exe, 0"); // Hot key for shortcut Shortcut.Hotkey = "Alt+CtrL+E"; Shortcut.Save(); // Create shortcut file. WScript.Echo("Shortcut file created."); ///////////////////////////////////////////////////////// // // Welcome // function Welcome() { var WshShell = WScript.CreateObject("WScript.Shell"); var intDoIt; intDoIt = WshShell.Popup(L_Welcome_MsgBox_Message_Text, 0, L_Welcome_MsgBox_Title_Text, vbOKCancel + vbInformation ); if (intDoIt == vbCancel) { WScript.Quit(); } } function MakePath(pathx) { // Create folder if it doesn't exist. var fso = new ActiveXObject("Scripting.FileSystemObject") if (!fso.FolderExists(pathx)) { var f = fso.CreateFolder(pathx); f = null; } fso = null; } //*** End |
NOTE
Are you looking for a way to enumerate all shortcuts on the Desktop or in a Start menu group? We won't discuss how to do this until Chapter 12, which covers file-handling features that use the FileSystemObject object. For now, you can achieve the same thing by getting the path to the destination folder and using the FileSystemObject object to enumerate all files with the .lnk extension in the special folder. You can then manipulate the .lnk files (rename or delete them, for example).
If you want to read and alter properties of an existing shortcut file, studying the Windows Script Host Reference won't help because it doesn't include any property access functions such as GetShortcut or ReadShortcut. After playing with the samples shown in this chapter, however, I found that applying the CreateShortcut method to an existing shortcut file doesn't alter its properties. This realization brought me to the clever idea of using the CreateShortcut object to access existing shortcut files.
Take a look at these statements:
Set Shortcut = WshShell.CreateShortcut(lnk_file) WScript.Echo Shortcut.TargetPath |
The first line creates a shortcut object whose name is submitted to the CreateShortcut method. The second line reads the TargetPath property of this object. If the shortcut file given in the variable lnk_file already exists, the CreateShortcut method reads the settings of the associated .lnk file. The line thus invokes a dialog box that shows the target path already defined for the shortcut.
The Arguments property contains extra arguments set in the shortcut. The Description property is supported by the WshShortcut object, but only Windows 2000 has a property sheet that displays it; Windows 95 and Windows 98 have no such item on their property sheets for shortcut files.
NOTE
The WshShortcut object doesn't support the properties used in Windows 2000 to run the process in a separate address space or under another user account. (See Figure 10-1.)
The following VBScript sample uses CreateShortcut to retrieve all properties from an existing shortcut file and display the results in a dialog box (Figure 10-4). If a property isn't set, the line is left blank in the dialog box. The IconLocation property returns the value ",0" if no icon is specified. In this case, the shortcut uses the default icon from the associated EXE program.
Figure 10-4 Displaying shortcut properties
The sample script comes with drag-and-drop support. The user can drag an existing shortcut file's icon to the script. After the user releases the left mouse button, the script is invoked with the name of the dragged file. The script then displays the properties of the file if it's a .lnk file.
The techniques for retrieving arguments submitted to a script are discussed in Chapter 7 (in the section "Accessing Script Arguments"). The following code checks whether the script was called with at least one argument:
Set objArgs = WScript.Arguments ' Create object. If objArgs.Count < 1 Then ' No argument found; warn user and ' end script. WScript.Echo " Sorry, no arguments were found!" , _ vbCrLf & vbCrLf, _ "Please drag the shortcut to the script's icon", _ "or call the script using:", vbCrLf & vbCrLf, _ "<host> GetShortcutProperties.vbs shortcut_file", _ vbCrLf & vbCrLf, _ "(Example: CScript.exe GetShortcutProperties.vbs C:\Editor.lnk)" WScript.Quit ' Quit script. End If |
After you retrieve the Arguments property, you can access the Arguments collection by using the object variable objArgs. The Count property of this object tells you whether the collection contains objects. If no objects are found, the script terminates with a simple dialog box that tells the user how to invoke the script program (Figure 10-5).
Figure 10-5 The dialog box that appears if no arguments were submitted
If an argument is obtained from the WScript.Arguments collection (the sample script supports only one filename at a time), you must at least check whether it's a shortcut file. Our sample simply checks to see whether the filename ends with the .lnk extension, using the following function:
Function IsLnk(name) ' Checks whether the extension is .lnk. ' Returns True or False. If (LCase(Right(name, 4)) = ".lnk") Then IsLnk = True Else IsLnk = False ' ".lnk" not found End If End Function |
The function must be called with a valid filename. It returns True or False, depending on the file's extension. The function extracts the last four characters of the filename, converts them to lowercase, and compares them with ". lnk ". The main script verifies the filename as follows:
If Not IsLnk(objArgs(0)) Then ' Check whether file has .lnk extension. WScript.Echo "Sorry, but '" & objArgs(0) & _ "' isn't a shortcut file." WScript.Quit End If |
The IsLnk function is called with the first item in the Arguments collection. If more than one argument is submitted, all other arguments are ignored. But it might be easy to extend the script to process multiple files dragged to the script file's icon.
NOTE
If the user drags a file to the script, you can assume that the filename is valid and a file exists, so the script checks only the filename extension. But it's much better also to check whether the filename belongs to an existing file. You do this by using the FileSystemObject object. We'll discuss this object in later chapters. For now, we'll omit this step. Another helpful step would be to check whether the file is a valid shortcut. This test involves using methods of the Windows Shell object.
After these tests are run, the script is ready to access the (hopefully) existing shortcut file with the following statement:
Set Shortcut = WshShell.CreateShortcut(objArgs(0)) |
At this point, you're ready to read and display the properties of the WshShortcut object, which are specified in the Shortcut object variable.
Listing 10-13 shows the entire script.
Listing 10-13 GetShortcutProperties.vbs
'************************************************************* ' File: GetShortcutProperties.vbs (WSH sample in VBScript) ' Author: (c) G. Born ' ' Retrieving the properties of a shortcut file submitted ' as an argument '************************************************************* Option Explicit Const Title = "Shortcut property viewer - by G. Born" Dim WshShell ' Object variable Dim objArgs, Shortcut ' Create a new WshShell object. Set WshShell = WScript.CreateObject("WScript.Shell") ' Try to retrieve the arguments. Set objArgs = WScript.Arguments ' Create object. If objArgs.Count < 1 Then ' No argument found; warn user and ' end script. WScript.Echo " Sorry, no arguments were found!" , _ vbCrLf & vbCrLf, _ "Please drag the shortcut to the script's icon", _ "or call the script using:", vbCrLf & vbCrLf, _ "<host> GetShortcutProperties.vbs shortcut_file", _ vbCrLf & vbCrLf, _ "(Example: CScript.exe GetShortcutProperties.vbs C:\Editor.lnk)" WScript.Quit ' Quit script. End If ' Try to get the argument submitted to the script. If Not IsLnk(objArgs(0)) Then ' Check whether file has .lnk extension. WScript.Echo "Sorry, but '" & objArgs(0) & _ "' isn't a shortcut file." WScript.Quit End If ' Try to create a shortcut file at the given location ' using the CreateShortcut method; if we don't use the Save ' method, no update is done. Set Shortcut = WshShell.CreateShortcut (objArgs(0)) MsgBox "File: " & objArgs(0) & vbCrLf & vbCrLf & _ "Arguments: " & vbTab & Shortcut.Arguments & vbCrLf & _ "Description: " & vbTab & Shortcut.Description & vbCrLf & _ "Full name: " & vbTab & Shortcut.FullName & vbCrLf & _ "Hotkey: " & vbTab & Shortcut.Hotkey & vbCrLf & _ "IconLocation: " & vbTab & Shortcut.IconLocation & vbCrLf & _ "Target: " & vbTab & Shortcut.TargetPath & vbCrLf & _ "WindowStyle: " & vbTab & Shortcut.WindowStyle & vbCrLf & _ "Working directory: " & vbTab & Shortcut.WorkingDirectory & _ vbCrLf, vbOKOnly + vbInformation, Title Function IsLnk(name) ' Checks whether the extension is .lnk. ' Returns True or False. If (LCase(Right(name, 4)) = ".lnk") Then IsLnk = True Else IsLnk = False ' ".lnk" not found End If End Function '*** End |
In the JScript version in Listing 10-14, only the IsLnk function uses a new feature: the GetExtensionName method of the FileSystemObject object. The filename must be submitted as a parameter. This sample implements the IsLnk function in such a way that two parameters (the filename and the .lnk extension) must be submitted.
Listing 10-14 GetShortcutProperties.js
//*********************************************************** // File: GetShortcutProperties.js (WSH sample in JScript) // Author: (c) G. Born // // Retrieves the properties of a shortcut file submitted // as an argument. //*********************************************************** // Create a new WshShell object. var WshShell = WScript.CreateObject("WScript.Shell"); // Try to retrieve the arguments. var objArgs = WScript.Arguments; // Create object. if (objArgs.length < 1) // No argument found; warn user and // end script. { WScript.Echo(" Sorry, no arguments were found!\n\n", "Please drag the shortcut to the script's icon", "or call the script using:\n\n", "<host> GetShortcutProperties.vbs shortcut_file\n\n", "(Example: CScript.exe GetShortcutProperties.vbs C:\Editor.lnk)"); WScript.Quit(); // Quit script. } // Try to get the argument submitted to the script. if (!IsLnk(objArgs(0), "lnk")) // Check whether file has // .lnk extension. { WScript.Echo("Sorry, but \'" + objArgs(0) + "\' isn't a shortcut file"); WScript.Quit(); } // Try to create a shortcut file at the given location // using the CreateShortcut method; if we don't use the Save // method, no update is done. var Shortcut = WshShell.CreateShortcut(objArgs(0)); WScript.Echo("File: " + objArgs(0) + "\n", "\nArguments: " + Shortcut.Arguments, "\nDescription: " + Shortcut.Description, "\nFull name: " + Shortcut.FullName, "\nHotkey: " + Shortcut.Hotkey, "\nIconLocation: " + Shortcut.IconLocation, "\nTarget: " + Shortcut.TargetPath, "\nWindowStyle: " + Shortcut.WindowStyle, "\nWorking directory: " + Shortcut.WorkingDirectory); ///////////////////////////////////////////////////////// // // IsLnk // // Checks whether the file has the given extension. // Returns true or false. function IsLnk(name, ext) { var fso = new ActiveXObject("Scripting.FileSystemObject"); var s = fso.GetExtensionName(name); var s1 = s.toLowerCase(); if (s1 == ext) { return (true); } else { return (false); } } //*** End |
TIP
The GetShortcutProperties sample is handy for finding out the icon number for a shortcut file. Windows itself doesn't provide a feature to find this number.
Updating a shortcut is simple. You can apply the CreateShortcut method to an existing shortcut and then read a property or set a new value. The Save method updates the shortcut file.
The following VBScript sample accepts a shortcut filename as a parameter. The icon used for this shortcut file is then set to a new value. You can submit the parameter in WSH 2 by dragging a shortcut file to the script's icon. For simplicity, our sample sets the icon by default to an image contained in the file Shell32.dll, which is available in all Windows versions.
NOTE
The location of Shell32.dll depends on the Windows version. In Windows 95 and Windows 98, the file is in the \System subfolder. In Windows NT and Windows 2000, it's in \System32.
The script must start by checking the version of the operating system. This sample implements the IsWinNT function for this purpose:
' IsWinNT checks whether the operating system is Windows 95 or ' Windows 98, or Windows NT or Windows 2000. Returns True or ' False. Needs WshShell object. Function IsWinNT Dim objEnv Set objEnv = WshShell.Environment("Process") If objEnv("OS") = "Windows_NT" Then IsWinNT = True Else IsWinNT = False End If End Function |
For the function to work, the main script must declare a WshShell variable and set that variable to an instance of the WshShell object. The function uses the WshShell variable to retrieve the environment variables for the process. The function then queries for the environment variable OS. This environment variable exists only in Windows NT and Windows 2000 and is set to Windows_NT in both operating systems. Depending on the value found, the function returns the value True or False.
The other techniques used in this sample are the same as in the previous sample. The script accepts two arguments. The first must be the filename of the shortcut file. The second argument is optional and can define the path and name of an icon file. The following are valid commands for invoking the script:
WScript.exe D:\ChangeShortcutIcon.vbs D:\C.lnk F:\WINNT\Explorer.exe,0 WScript.exe D:\ChangeShortcutIcon.vbs D:\C.lnk D:\B.ico |
If the user drags a.lnk file to the script's icon, a default icon is obtained from Shell32.dll. After obtaining the parameters, the script creates a shortcut object (which contains the properties of an existing .lnk file). Then the IconLocation property is set to the second argument, and this modification is stored using the Save method.
Listing 10-15 shows the entire script. I'll leave it to you to implement the sample in JScript.
Listing 10-15 ChangeShortcutIcon.vbs
'********************************************************** ' File: ChangeShortcutIcon.vbs (WSH sample in VBScript) ' Author: (c) G. Born ' ' Changing the shortcut icon of the Registry Editor's ' shortcut on the Desktop '********************************************************** Option Explicit Const Ready_txt = "Shortcut icon changed" Const Text = "Change shortcut icon?" Const Title = "Shortcut icon changer - by G. Born" Dim WshShell ' Object variable Dim objArgs, Shortcut Dim Arg(2) Dim status, i ' Create a new WshShell object. Set WshShell = WScript.CreateObject("WScript.Shell") ' Initialize icon path (if only one argument is submitted). ' Expand environment variable to get default icon (from Explorer). Arg(1) = WshShell.ExpandEnvironmentStrings("%WINDIR%") ' Try to detect the operating system. If IsWinNT Then Arg(1) = Arg(1) & "\System32\Shell32.dll, 19" Else Arg(1) = Arg(1) & "\System\Shell32.dll, 19" End If ' Try to retrieve the arguments. Set objArgs = WScript.Arguments ' Create object. If objArgs.Count < 1 Then ' No argument found; warn user and ' end script. WScript.Echo "Changes the icon of a given shortcut", _ vbCrLf & vbCrLf, _ "Sorry, no arguments were found!" , vbCrLf, _ "Please drag the shortcut to the script's icon", _ "or call the script using:", vbCrLf & vbCrLf, _ "<host> ChangeShortcutIcon.vbs shortcut_file icon_file", _ vbCrLf & vbCrLf, _ "(Example: CScript.exe ChangeShortcutIcon.vbs C:\Editor.lnk " & _ "D:\Bmp\Book.bmp)" WScript.Quit ' Quit script. End If ' Try to get the arguments submitted to the script. If only one ' argument is present, use the default icon specified above. For i = 0 to objArgs.Count - 1 ' Loop through all arguments. Arg(i) = objArgs(i) ' Get argument. Next If Not IsLnk(Arg(0)) Then ' Check whether file has .lnk extension. WScript.Echo "Sorry, but '" & Arg(0) & "' isn't a shortcut file." WScript.Quit End If ' Ask the user whether the shortcut icon should be modified. status = MsgBox(Text, _ vbYesNo + vbQuestion, _ Title) If (status <> vbYes) Then WScript.Quit 1 ' Cancel selected. End If ' We know the path to the shortcut file and the icon location. ' Use the CreateShortcut method to update the shortcut. Set Shortcut = WshShell.CreateShortcut(Arg(0)) ' Change shortcut icon. Shortcut.IconLocation = Arg(1) Shortcut.Save ' Update shortcut file. WScript.Echo Ready_txt ' Ready message Function IsLnk(name) ' Checks whether the extension is .lnk. ' Returns True or False. If (LCase(Right(name, 4)) = ".lnk") Then IsLnk = True Else IsLnk = False ' ".lnk" not found End If End Function ' IsWinNT checks whether the operating system is Windows 95 or ' Windows 98, or Windows NT or Windows 2000. Returns True or ' False. Needs WshShell object. Function IsWinNT Dim objEnv Set objEnv = WshShell.Environment("Process") If objEnv("OS") = "Windows_NT" Then IsWinNT = True Else IsWinNT = False End If End Function '*** End |
A link to a Web site placed on the Desktop is a special version of a shortcut. If you use the filename extension .url rather than .lnk, Windows creates a link to the Web site. You'll recognize this type of shortcut because it uses an icon for Web documents.
WSH has a few features for creating this type of shortcut. You can use the CreateShortcut method and TargetPath property of the WshShell object. The VBScript program in Listing 10-16 creates a link to a Web site on the Desktop. It differs from the previous samples in that the shortcut file has a .url extension and the TargetPath property doesn't contain a path. Instead, the property is set to the URL of the Web site.
Listing 10-16 URLShortcut.vbs
'*************************************************** ' File: URLShortcut.vbs (WSH sample in VBScript) ' Author: (c) G. Born ' ' Creating a shortcut to a URL on the desktop '*************************************************** Option Explicit Dim Text, Title, oURL Dim WshShell ' Object variable Dim status, Ready_txt, path Ready_txt = "URL shortcut created" Text = "Create URL shortcut on the Desktop?" Title = "WSH sample - by G. Born" ' Ask user before creating the shortcut. status = MsgBox(Text, _ vbYesNo + vbInformation, _ Title) If (status <> vbYes) Then WScript.Quit 1 ' User clicked No. End If ' Create WshShell object, which we need for the ' WshSpecialFolders object. Set WshShell = WScript.CreateObject("WScript.Shell") ' Get path to the Desktop folder using the ' WshSpecialFolders object. Path = WshShell.SpecialFolders("Desktop") ' Use CreateShortcut method to create shortcut. Set oURL = WshShell.CreateShortcut(path & "\Microsoft.URL") ' Set shortcut properties. oURL.TargetPath = "http://www.microsoft.com" oURL.Save ' Create shortcut. WScript.Echo Ready_txt ' Ready message '*** End |
The JScript version is shown in Listing 10-17.
Listing 10-17 URLShortcut.js
//************************************************* // File: URLShortcut.js (WSH sample in JScript) // Author: (c) G. Born // // Creating a shortcut to a URL on the Desktop //************************************************* var vbOKCancel = 1; var vbInformation = 64; var vbCancel = 2; var L_Welcome_MsgBox_Message_Text = "Creates a URL shortcut on the Desktop"; var L_Welcome_MsgBox_Title_Text = "WSH sample - by G. Born"; Welcome(); // Welcome dialog box // Get object with method for creating shortcut. var WshShell = WScript.CreateObject("WScript.Shell"); // Get Desktop path using WshSpecialFolders object. var Path = WshShell.SpecialFolders("Desktop"); // Create shortcut on Desktop. var oURL = WshShell.CreateShortcut(Path + "\\Microsoft.URL"); // Set shortcut properties. First, the target path. oURL.TargetPath = "http://www.microsoft.com"; oURL.Save(); // Store shortcut. WScript.Echo("Shortcut created"); ///////////////////////////////////////////////////////// // // Welcome // function Welcome() { var WshShell = WScript.CreateObject("WScript.Shell"); var intDoIt; intDoIt = WshShell.Popup(L_Welcome_MsgBox_Message_Text, 0, L_Welcome_MsgBox_Title_Text, vbOKCancel + vbInformation ); if (intDoIt == vbCancel) { WScript.Quit(); } } //*** End |