[Previous] [Table of Contents] [Next]

# Accessing Environment Variables

Windows 95, Windows 98, Windows NT 4, and Windows 2000 store several kinds of information in environment variables. An environment variable contains a string value. You can display environment variables and their content in the Command Prompt window by using the Set command.

Figure 7-4 shows a Command Prompt window containing environment variables on a machine running Windows 2000. If you examine the environment variables on machines running Windows 95 or Windows 98, you'll notice that the variable names differ from those in Windows 2000. Windows 95 and Windows 98 inherited their environment variables from MS-DOS, so you'll find only a few variables, such as PATH, PROMPT, and WINDIR.

Figure 7-4 Environment variables in Windows 2000

Windows NT and Windows 2000 use many more environment variables than Windows 95 and Windows 98. In Windows NT and Windows 2000, you can retrieve the operating system name, the number of processors, the platform, and so on.

## Accessing Environment Variables in a Script

One use for environment variables is to tell the script what platform (Intel or Alpha) the code is executed on. You can also determine which operating system (Windows 98 or Windows 2000) is being used. But you must be careful because, as just mentioned, Windows 2000 environment variables are different from environment variables in Windows 95 and Windows 98.

How do you access the environment variables in a script? To access environment variables on a particular system, you can use the Environment property of the WshShell object, which returns the WshEnvironment collection object. According to the Windows Script Host Reference, the Environment property has the following syntax:

    object.Environment([strType])

The index strType specifies the category in which the environment variable resides. In Windows NT and Windows 2000, the operating system groups environment variables internally into the System, User, Volatile, and Process categories, so you can use the "System", "User", "Volatile", or "Process" string as the index. In Windows 95 and Windows 98, the method supports only the "Process" entry. If you omit the index value, the method retrieves the environment variables from the System category in Windows NT or Windows 2000. In Windows 95 and Windows 98, the method retrieves the Process environment variables because Process is the only category supported.

Table 7-3 describes some of the environment variables the operating system sets.

You can use the following statements to access the Environment property:

    Set WshShell = CreateObject("WScript.Shell")
    Set objEnv = WshShell.Enviroment("Process")

The first line creates a reference to the WshShell object and stores it in the object variable WshShell. The next statement uses this object variable to access the Environment property. The parameter specifies the category in which the environment variables reside. Environment returns a collection object, so you must assign the result to an object variable by using the Set statement. (The items in the collection are the values of the environment variables in the category.)

This next line retrieves the value of a specific environment variable:

    Text = objEnv("PATH")

This statement requires that objEnv contain a collection obtained from the Environment property. The index for the objEnv object must contain the name of an environment variable. The preceding statement assigns the value of the environment variable PATH to the variable Text.

Table 7-3 Environment Variables Set by the Operating System

Name | Description | Windows NT or Windows 2000 System | Windows NT or Windows 2000 User | Windows NT or Windows 2000 Process | Windows 95 or Windows 98 Process
--- | --- | --- | --- | --- | ---
COMSPEC | Executable for Command Prompt (typically cmd.exe or command.com). | X |  | X | X
HOMEDRIVE | The primary local 4 drive (typically C:\). |  |  | X |
HOMEPATH | The default directory for users (typically \users\default). |  |  | X |
NUMBER_OF_PROCESSORS | The number of processors running on the machine. | X |  | X |
OS | Operating system on the user's machine. | X |  | X |
PATH | The path. |  |  | X | X
PATHEXT | Extensions for executable files (typically .com, .exe, .bat, or .cmd). | X |  | X |
PROCESSOR_ARCHITECTURE | The processor type of the user's machine. | X |  | X |
PROCESSOR_IDENTIFIER | The processor ID of the user's machine. | X |  | X |
PROCESSOR_LEVEL | The processor level of the user's machine. | X |  | X |
PROCESSOR_REVISION | The processor version of the user's machine. | X |  | X |
PROMPT | Command prompt (typically $P$G) for MS-DOS. |  |  | X | X
SYSTEMDRIVE | The local drive on which the system directory resides (C:\, for example). |  |  | X |
SYSTEMROOT | The system directory (such as C:\WINNT); the same as WINDIR. |  |  | X |
TEMP | Directory for storing temporary files (C:\temp, for example). Available in all Windows versions. In Windows NT, contained in the categories User and Volatile. |  | X | X | X
TMP | Directory for storing temporary files (C:\temp, for example). Available in all Windows versions. Categories: User and Volatile under Windows NT. |  | X | X | X
WINDIR | System directory under Windows NT (such as C:\WINNT); same as SYSTEMROOT. | X |  | X | X

> NOTE

> For a list of predefined environment variables and a description of their methods and properties, see the Windows Script Host Reference.

### Accessing environment variables in VBScript

The program in Listing 7-8 reads system environment variables and a user-defined environment variable and displays their values in a dialog box. (The user-defined variable, BLASTER, stores hardware settings for certain sound cards.)

You can execute the script in Windows 95, Windows 98, Windows NT 4, or Windows 2000 (as long as WSH is installed). The environment variables shown will depend on the operating system platform. For example, Windows 98 doesn't recognize the environment variable OS (which indicates the operating system platform).

Figure 7-5 shows the dialog box displayed by the script in Windows 2000. Because several environment variables (OS, BLASTER) are not defined on this platform, some entries are empty. (Only the variable name is shown.) If you execute this script in Windows 95 or Windows 98, not all entries will contain values.

Figure 7-5 Environment variables retrieved by Environment.vbs

> TIP

> You can use the environment variable OS to detect the operating system platform. If the environment variable is undefined (an empty string is returned), the script is running in Windows 95 or Windows 98. In Windows NT, you can also test for the platform (x86 or Alpha).

Listing 7-8 accesses environment variables in VBScript.

Listing 7-8 Environment.vbs

    '***************************************************
    ' File:    Environment.vbs (WSH sample in VBScript)
    ' Author:  (c) G. Born
    '
    ' Displaying environment variables by using the
    ' WshShell object
    '***************************************************
    Option Explicit

    Dim Message, Title
    Dim WshShell, objEnv

    ' Get the WshShell object.
    Set WshShell = CreateObject("WScript.Shell")

    ' Get collection by using the Environment property.
    Set objEnv = WshShell.Environment("Process")

    ' Read environment variables.
    Message = "Environment variables" & vbCrLf & vbCrLf
    Message = Message & "Path: " & objEnv("PATH") & vbCrLf
    Message = Message & "Extensions: " & objEnv("PATHEXT") & vbCrLf
    Message = Message & "Prompt: " & objEnv("PROMPT") & vbCrLf

    Message = Message & "System Drive: " & objEnv("SYSTEMDRIVE") & vbCrLf
    Message = Message & "System Root: " & objEnv("SYSTEMROOT") & vbCrLf
    Message = Message & "Windows Directory: " & objEnv("WINDIR") & vbCrLf

    Message = Message & "TEMP: " & objEnv("TEMP") & vbCrLf
    Message = Message & "TMP: " & objEnv("TMP") & vbCrLf

    Message = Message & "OS: " & objEnv("OS") & vbCrLf

    ' Get user-defined environment variable.
    Message = Message & "Blaster: " & objEnv("BLASTER") & vbCrLf

    ' Initialize title text.
    Title = "WSH sample " & WScript.ScriptName & " - by G. Born"

    MsgBox Message, vbInformation & vbOKOnly, Title

    '*** End

### Accessing environment variables in JScript

The sample in Listing 7-9 reads the same environment variables as the preceding VBScript sample and shows the results in a dialog box. Not all environment variables are defined on every platform.

Listing 7-9 Environment.js

    //***************************************************
    // File:     Environment.js (WSH sample in JScript)
    // Author:   (c) G. Born
    //
    // Displaying environment variables by using the
    // WshShell object
    //***************************************************

    var Message, Title;
    var vbInformation = 64;
    var vbOKOnly = 0;

    // Get WshShell object.
    var WshShell = WScript.CreateObject("WScript.Shell");

    // Get collection by using the Environment property.
    var objEnv = WshShell.Environment("Process");

    // Read environment variables.
    Message = "Environment variables\n\n";
    Message = Message + "Path: " + objEnv("PATH") + "\n";
    Message = Message + "Extensions: " + objEnv("PATHEXT") + "\n";
    Message = Message + "Prompt: " + objEnv("PROMPT") + "\n";

    Message = Message + "System Drive: " + objEnv("SYSTEMDRIVE") + "\n";
    Message = Message + "System Root: " + objEnv("SYSTEMROOT") + "\n";
    Message = Message + "Windows Directory: " + objEnv("WINDIR") + "\n";

    Message = Message + "TEMP: " + objEnv("TEMP") + "\n";
    Message = Message + "TMP: " + objEnv("TMP") + "\n";

    Message = Message + "OS: " + objEnv("OS") + "\n";

    // Get user-defined environment variable.
    Message = Message + "Blaster: " + objEnv("BLASTER") + "\n";

    // Initialize title text.
    Title = "WSH sample " + WScript.ScriptName + " - by G. Born";

    WshShell.Popup(Message, vbInformation + vbOKOnly, Title);

    //*** End

### Setting environment variables

In the Command Prompt window, you can set environment variables only for the current process. Environment variables created in the Command Prompt window are volatile—they're lost when you end the session. In Windows 95 and Windows 98, you can set a permanent environment variable by using the Set command in the Autoexec.bat file. In Windows NT and Windows 2000, you must use the Environment Variables dialog box to set the environment variables. (In Control Panel, double-click on the System icon, select the Advanced property page, and click the Environment Variables button.) As a result, you can't create a permanent environment variable in a WSH script. All environment variables that you create are volatile because when you execute a script, Windows creates a copy of the master environment in the address space of the new process. Access to the environment means access to the local copy. If the process terminates, the associated address space is released and the variables are lost.

To demonstrate this temporary nature of environment variables, I've written a small VBScript program, Environment1.vbs, which starts with a dialog box that asks the user whether a new environment variable BORN should be created. If the user clicks Yes, the script creates the new environment variable, as shown here:

    Set WshShell = CreateObject("WScript.Shell")
    Set objEnv = WshShell.Environment("Process")
    objEnv("BORN") = "Hello. WSH is super!"

The first statement creates a reference to the WshShell object. The second line accesses the Environment property, which contains the collection with all environment variables of the Process category. (Using the Process category assures that this script can also be executed with full results in Windows 95 and Windows 98.) The third statement creates the new environment variable, named BORN, and assigns a string to it. If the variable doesn't exist, a new entry is created in the local environment of the WSH process.

The code in Listing 7-10 lists all environment variables found after the new entry is created by rereading the Environment property and accessing all entries of the collection by using a For Each…In loop.

> NOTE

> If you want to analyze the lifetime of an environment variable, when the Environment1.vbs script asks whether you want to create the new variable and list all environment variables in the environment in a dialog box, click Yes and leave the new dialog box displayed. Start a second copy of the WSH script, and click No to prevent a new variable from being created. The second dialog box won't contain the entry BORN, which means that the environment variables created from the first process are local. If you terminate the script and restart it without creating a new environment variable, you'll see a dialog box without the entry BORN. This experiment indicates that the lifetime of a variable is coupled with the lifetime of the current process.

Listing 7-10 Environment1.vbs

    '****************************************************
    ' File:    Environment1.vbs (WSH sample in VBScript)
    ' Author:  (c) G. Born
    '
    ' Creating an environment variable, reading all
    ' the environment variables in the Process category,
    ' and displaying the results in a dialog box
    '****************************************************
    Option Explicit

    Dim Message, Title
    Dim WshShell, objEnv
    Dim i, tmp

    ' Get WshShell object.
    Set WshShell = CreateObject("WScript.Shell")

    ' Get collection by using the Environment property.
    Set objEnv = WshShell.Environment("Process")

    ' Create a (temporary) environment variable.
    tmp = MsgBox("Create environment variable BORN?", _
            vbYesNo + vbQuestion, _
            "WSH sample - by G. Born")

    If tmp = vbYes Then
        objEnv("BORN") = "Hello. WSH is super!"
    End If

    ' Read environment variables.
    Message = "Environment variables" & vbCrLf & vbCrLf

    For Each i In objEnv
        Message = Message & i & vbCrLf
    Next

    ' Initialize title text.
    Title = "WSH sample " & WScript.ScriptName & " - by G. Born"

    MsgBox Message, vbInformation + vbOKOnly, Title

    '*** End

> NOTE

> If a script launches a second script using the Run method, the environment variables created from the child script can be accessed from the parent script.

### Deleting environment variables

The Environment object supports a Remove method for deleting an environment variable. You can use this method as follows:

    Set WshShell = WScript.CreateObject("WScript.Shell")
    WshShell.Environment("Process").Remove("PATH")

This method accesses only the local environment variables of the current process. This means that the environment variable is deleted only within this copy of the environment. All global environment variable settings remain.

Listing 7-11 tests this behavior. In the first step, all environment variables (the original state) are shown in a dialog box. Then a new variable, BORN, is added to the environment. The content of all environment variables is shown a second time. In step 3, the script deletes the environment variables BORN and PATH. The result is shown in a third dialog box. If you start the script again, the environment variable PATH remains. A WSH script can't delete an environment variable permanently.

Listing 7-11 Environment2.vbs

    '****************************************************
    ' File:    Environment2.vbs (WSH sample in VBScript)
    ' Author:  (c) G. Born
    '
    ' Creating and deleting an environment variable
    ' in the Process category
    '****************************************************
    Option Explicit

    Dim Message, Title
    Dim WshShell, objEnv
    Dim i

    ' Get WshShell object.
    Set WshShell = CreateObject("WScript.Shell")

    ' Get collection by using the Environment property.
    Set objEnv = WshShell.Environment("Process")

    ' Initialize title text.
    Title = "WSH sample " & WScript.ScriptName & " - by G. Born"

    ' Read environment variables.
    Message = "Environment variables (original state)" & vbCrLf & vbCrLf

    For Each i In objEnv
        Message = Message & i & vbCrLf
    Next

    MsgBox Message, vbInformation + vbOKOnly, Title

    ' Create a (temporary) environment variable.
    objEnv("BORN") = "Hello. WSH is super!"

    ' Read environment variables.
    Message = "Environment variables (extended)" & vbCrLf & vbCrLf

    For Each i In objEnv
        Message = Message & i & vbCrLf
    Next

    MsgBox Message, vbInformation + vbOKOnly, Title

    ' Delete the environment variables.
    objEnv.Remove("BORN")
    objEnv.Remove("PATH")

    ' Read the environment variables.
    Message = "Environment variables (after deleting)" & vbCrLf & vbCrLf

    For Each i In objEnv
        Message = Message & i & vbCrLf
    Next

    MsgBox Message, vbInformation & vbOKOnly, Title

    '*** End

### Expanding environment variables by using ExpandEnvironmentStrings

There's another technique you can use to retrieve the information stored in environment variables. If you've created MS-DOS batch programs, you probably know how to use the content of an environment variable in a batch command. For example, the following command uses the content of the environment variable TEXT to set the path to the editor:

    %TEXT%\Edit.com %DOCUMENT%

The document, which will be loaded, is defined in the environment variable DOCUMENT. You can use a similar approach in the Registry in Windows NT or Windows 2000. For example, this Registry entry causes Windows to insert the path to the Windows folder into the placeholder %WINDIR%:

    %WINDIR%\Notepad.exe %1

If Windows is installed in the folder C:\WINNT, the command is expanded as follows:

    C:\WINNT\Notepad.exe %1

> NOTE

> The characters %1 are a placeholder for the file selected in the shell and have nothing to do with environment variables.

The advantage of using the %WINDIR% placeholder is that the command is valid no matter where the user installs the operating system.

As a script programmer, you probably prefer to use certain path definitions to build your commands. But you can't be sure that absolute paths defined in your script will remain valid for a long time and on different machines. For example, if you want to specify the folder in which the user has installed Windows, you can access the environment variable WINDIR (in Windows 95 or Windows 98), which is created at system startup and contains the current path to the Windows folder. By using the WINDIR environment variable instead of a hard-coded path, your script will always find the Windows directory, even if the path differs from machine to machine.

How can a script access this information about the Windows folder? And how can you use the content of another environment variable within an expression? One approach is to use the methods and properties already mentioned to read the content of the environment variables and then to insert the result into the expression. But before you try this, I'd like to show you a simpler solution.

In Chapter 6, we used the WshShell object to access the Popup method. This object also exposed other methods. Table 7-4 describes the methods of the WshShell object.

Table 7-4 Methods of the WshShell Object

Method | Description
--- | ---
CreateShortcut | Creates a WshShortcut or WshURLShortcut object and returns it
ExpandEnvironmentStrings | Expands a Process environment variable and returns the result string
Popup | Shows a message box containing specified text
RegDelete | Deletes a specified key or value from the Registry
RegRead | Reads a Registry key or value
RegWrite | Sets a Registry key or value
Run | Creates a new process that executes a specified command with a specified window style

The ExpandEnvironmentStrings method of the WshShell object requests a string as a parameter. If this string contains the name of an environment variable enclosed in % characters, the method expands this name with the content of the variable and returns the expanded string. If you insert the name of an environment variable into a command, you can easily expand the command using this method.

The VBScript sample in Listing 7-12 uses this approach. The script contains the following command, which expands the environment variable %WINDIR%:

    Command = "%WINDIR%\Explorer.exe"   ' Command to be expanded

The result is shown in a dialog box. (See Figure 7-6.)

Figure 7-6 An expanded environment variable

> NOTE

> The Run method automatically expands all environment variables in the format %...% in a command string.

Listing 7-12 Environment3.vbs

    '****************************************************
    ' File:    Environment3.vbs (WSH sample in VBScript)
    ' Author:  (c) G. Born
    '
    ' Using the ExpandEnvironmentStrings method of the
    ' WshShell object
    '****************************************************
    Option Explicit

    Dim Command
    Dim WshShell

    Command = "%WINDIR%\Explorer.exe"   ' Command to be expanded

    ' Get WshShell object.
    Set WshShell = WScript.CreateObject("WScript.Shell")

    ' Now we can use the ExpandEnvironmentStrings method.
    WScript.Echo "Command: " & Command & vbCrLf & _
                 "Expanded: " & WshShell.ExpandEnvironmentStrings(Command)

    '*** End

In JScript, you can use a similar approach, but you use escape characters to define a command string with \ characters. Thus, the command %WINDIR%\Explorer.exe must be written as %WINDIR%\\Explorer.exe. After defining the command string, you retrieve a reference to WshShell and assign it to an object variable. Then you can use a string containing the environment variable name and pass it to the ExpandEnvironmentStrings method, as shown in Listing 7-13.

Listing 7-13 Environment3.js

    //**************************************************
    // File:    Environment3.js (WSH sample in JScript)
    // Author:  (c) G. Born
    //
    // Using the ExpandEnvironmentStrings method of the
    // WshShell object
    //**************************************************

    var Command = "%WINDIR%\\Explorer.exe";   // Command to be expanded

    // Get WshShell object.
    var WshShell = WScript.CreateObject("WScript.Shell");

    // Now we can use the ExpandEnvironmentStrings method.
    WScript.Echo("Command:  " + Command,
            "\nExpanded: " + WshShell.ExpandEnvironmentStrings(Command));

    //*** End