Previous Section Table of Contents Next Section

The Shell Object

The Shell object must be explicitly created and assigned to a variable, just like the Network object. In this section, I'll assume that your scripts already contain the following code.


'Create shell object

Set oShell = CreateObject("WScript.Shell")

Overview

You can use the Shell object to execute external applications, work with special folders and shortcuts, manipulate environment variables, write to the event log, read and write to the registry, create timed dialog boxes, and even send keystrokes to another application. Shell is sort of the catchall of the WSH, containing a number of useful functions.

Methods and Properties

The Shell object's methods and properties provide access to its functionality. Many of these methods and properties are complementary, so I'll discuss them together in the following sections.

Run and Exec

Scripting can't do it all. That's an important thing to remember. I always set myself a research time limit: If I can't figure out how to do something in script within 30 minutes of searching on the Web, I'll do it whatever way I already know how. If that means launching an external command line, so be it. A good example is setting NTFS permissions on files and folders. You can absolutely do that from within WMI, but it's a thankless, complicated task. I've taken the pain to figure it out a few times, but it's almost always easier to just launch Cacls.exe with the appropriate parameters, so that's what I usually do, using Run and Exec.

Both methods launch new applications in separate processes. With Run, that process is completely detached from your script, and your script will have no access to it. Most of the time, that's fine. With Exec, your script has access to the new process' input and output streams, meaning you can read the output of command-line utilities or other applications into your script, and then do something else based on what happened.

Here's how you can use Run to launch the DIR command.


Call oShell.Run("cmd /c dir " & _

 "/a")

Notice that you have to launch the command-line processor, CMD, first; you can tell it to run DIR for you. This is an interesting technique, but not useful, as your script has no way to get at the DIR results. You could have DIR redirect its output to a text file, and then read in the text file…but what a pain. There's an easier way.


Dim oExecObject, sDir

Set oExecObject = oExec("cmd /c dir /a")

Do While Not oExecObject.StdOut.AtEndOfStream

 sDir = sDir & oExecObject.StdOut.Readline()

Loop

WScript.Echo sDir

In this example, the Exec method is used, which returns an execution object. That object actually represents the process space of the command window that's running DIR for you. That process has a standard input (StdIn) and standard output (StdOut) property, which you can utilize. In this example, the script is reading the StdOut property line-by-line until there are no more lines to read. Then, the script displays the results. You could, of course, read the results into an array and allow the user to select a specified folder, or whatever you want to do with the output.

You might be wondering why Run is even included if Exec is so useful. Here's why: With Run, you can control the type of window the new process occupies. Simply include a second parameter to Run with one of the following numbers:

  • 0: Hidden window

  • 1: Normal window with focus

  • 2: Minimized window with focus

  • 3: Maximized window with focus

  • 4: Display window in its default size, without focus

  • 5: Activate the window

  • 6: Minimize the window and give focus to the next window up in the Z-order

  • 7: Minimized window without focus

  • 8: Default size without focus

  • 9: Display the window with focus

The focus, of course, refers to the active window. Specifying 7, for example, launches the new application in a minimized window while leaving the current window active. This is nice for running background processes that you don't necessarily want the script's user to see.

Run accepts a third optional parameter, True or False, that decides whether your script will pause and wait for the launched application to finish and quit or launch the application and then continue execution right away. Try this.


Call oShell.Run("notepad.exe",,True)

MsgBox "Wow, that took a long time"

You'll notice the two serial commas in the Run statement. That's because I didn't want to specify a window style, which is the second parameter. This script executes Notepad, and then continues by displaying a message only after you close Notepad.

SpecialFolders

There may be times when you want to create a shortcut in, or copy a file to, one of Windows' "special" folders, such as My Documents or the Desktop. The SpecialFolders method allows you to figure out the actual path of these special folders so that you can utilize them. Here's how.


Dim sPath

sPath = oShell.SpecialFolders("name")

Simply replace name with one of the following:

  • AllUsersDesktop

  • AllUsersStartMenu

  • AllUsersPrograms

  • AllUsersStartup

  • Desktop

  • Favorites

  • Fonts

  • MyDocuments

  • NetHood

  • PrintHood

  • Recent

  • SendTo

  • StartMenu

  • Startup

  • Templates

CreateShortcut

The CreateShortcut method is a quick and dirty way to create shortcuts; the CreateShortcut method returns a Shortcut object, which I'll discuss later in this chapter. The basic syntax looks like this.


Dim oShortcut

Set oShortcut = oShell.CreateShortcut(path)

After the shortcut is created, you use the properties of the Shortcut object to set its target, shortcut keys, and so forth.

Environment

Environment variables are a useful way to access critical system information, such as the path of the Windows folder. The Environment object provides access to this information and allows you to manipulate it. There are actually different categories of environment variables: Computer-specific variables and user-specific variables are the two main ones you'll work with. The user-specific variables are stored in a space named "User," whereas computer-specific variables are stored in "System."

Some variables exist in both locations. For example, "PATH" exists both in the "User" and "System" spaces. Why should you care? Because you can also modify these variables. If you modify the "System" space, you're changing the entire computer, even after the current user logs off. If you just want to change an environment variable for your script, use the special "Process" space, which only exists until your script stops running.

Here's how you can retrieve an environment variable.


'get the system space

Dim oEnv

Set oEnv = oShell.Environment("System")



'get the PATH

WScript.Echo oEnv("PATH")

You can modify them using a similar technique.


'get the system space

Dim oEnv

Set oEnv = oShell.Environment("System")



'get the PATH

oEnv("PATH") = "new path"

ExpandEnvironmentStrings

Environment variables can sometimes contain expandable strings, such as "%systemroot%". You can use ExpandEnvironmentStrings to expand these into their full values.


Dim oEnv

Set oEnv = oShell.Environment("System")

WScript.Echo oShell.ExpandEnvironmentStrings("%TEMP%")

LogEvent

Need to log an event to the Windows Event log? No problem.


oShell.LogEvent 0, "Success!"

oShell.LogEvent 2, "Warning!"

The second parameter is a simple string and will be logged in the event itself. All events are logged to the Application log. The first parameter specifies the type of event:

  • 0: Success

  • 1: Error

  • 2: Warning

  • 3: Informational

  • 8: Audit Success

  • 16: Audit Failure

RegRead, RegWrite, and RegDelete

Working with the registry is easy using the Shell object. Obviously, the usual caveats and warnings about editing the registry apply: You're messing with the heart and soul of Windows here, so exercise caution.

To read information from the registry:


sVariable = oShell.RegRead( _To read information from the registry:

 "HKLM\SOFTWARE\Microsoft\Windows NT\" & _

 "CurrentVersion\CurrentVersion")

You must provide the complete path to the value you're interested in. Shortcut HKEY_LOCAL_MACHINE by using HKLM; HKEY_ CURRENT_ USER becomes HKCU, and so forth. To create or modify a value, you'll need to know the path, the data for the value, and the data type.


oShell.RegWrite( _

 "HKLM\SOFTWARE\Company\Key\Value", "Data", "REG_SZ")

Data types are

  • REG_SZ for strings

  • REG_DWORD for numbers

  • REG_BINARY for byte data

  • REG_EXPAND_SZ for expandable strings

  • REG_MULTI_SZ for string arrays

If you try to modify a value that doesn't exist, Windows will create it for you. Deleting a key simply requires you to know its name.


oShell.RegDelete( _

 "HKCU\SOFTWARE\Test")

AppActivate

Your scripts not only can launch external applications using Run and Exec, but can also activate already running applications. You just need to know the window title, or a portion of it.


oShell.AppActivate _

 "Notepad"

After the application is active and has the system focus, you can send keystrokes to it using SendKeys.

SendKeys

Try this script.


oShell.Run "Notepad.exe"

Wscript.Sleep 5000

oShell.AppActivate "Notepad"

oShell.SendKeys "Ghost writing is fun."

TIP

Notice the Sleep command. This gives Notepad time to launch before the script activates it and starts sending keystrokes to it.


SendKeys allows you to send keystrokes to other applications. This is a wonderful way to control applications that don't provide any other means of doing so; effectively, you're writing your own old-style macros to control the application's functions. You can even send special keys by using the following strings along with SendKeys:

  • {BS} Backspace

  • {BREAK} Break

  • {CAPSLOCK} Caps lock

  • {DEL} Delete

  • {DOWN} Down arrow

  • {END} End

  • {ENTER} Enter

  • {ESC} Escape

  • {HELP} Help

  • {HOME} Home

  • {INS} Insert

  • {LEFT} Left arrow

  • {NUMLOCK} Num lock

  • {PGDN} Page down

  • {PGUP} Page up

  • {PRTSC} Print screen

  • {RIGHT} Right arrow

  • {SCROLLLOCK} Scroll lock

  • {TAB} Tab

  • {UP} Up arrow

  • + Shift key, as in +P for Shift+P

  • ^ Control key, as in ^P for Ctrl+P

  • % ALT key, as in %P for Alt+P

Notice that the special keys must be enclosed in curly brackets (braces) as shown, except for Shift, Alt, and Control key combinations.

Popup

You've already seen the MsgBox statement and used it to display dialog boxes; the Popup method displays similar boxes, but puts a time limit and a default response on them. To display a five-second notification:


oShell.Popup _

 "Everything is complete", 5

You can use the same values as the MsgBox statement, which I covered in Chapter 6, to display icons and buttons. For example, to display a critical error with Yes and No buttons, and to make it time out and accept the default:


oShell.Popup _

 "Severe error. Continue?", 5, 16 + 4

    Previous Section Table of Contents Next Section