[Previous] [Table of Contents] [Next]

# Paths and Dates

To access external files, you need the path to those files. In this section, we'll examine how to obtain the current script file's folder, the default folder, or the drive. I'll also explain a pitfall of using date differences.

## Getting the Script's Path

Sometimes it's handy to know the path to your script—for example, when you want to process files in your script's folder. Using the script's path as a working folder is less error-prone than using absolute paths because the script's path is always valid (even after renaming the script folder or moving it to another drive). WSH has no function or method for retrieving a script's path, so in VBScript you can use the ScriptFullName property of the WScript object to extract the path, as shown here:

    Function GetPath
        ' Retrieve path to the script file.
        Dim path
        path = WScript.ScriptFullName  ' Script filename
        GetPath = Left(path, InStrRev(path, "\"))
    End Function

In JScript, you can use the following function to retrieve the path:

    function GetPath()
    {
        // Retrieve the script path.
        var path = WScript.ScriptFullName;  // Script filename
        path = path.substr(0, path.lastIndexOf("\\") + 1);
        return path;
    }

Both functions assume that the path ends with a backslash character. If WSH is ever ported to other operating systems (such as Macintosh or UNIX), this method of extracting the path might fail. In this case, you can use the following construction instead:

    path = Left(Wscript.ScriptFullName, _
                Len(Wscript.ScriptFullName) - Len(Wscript.ScriptName))

This statement simply subtracts the script filename from the full name, so it's independent of the file-naming convention. If you don't want to use this trick, you can use the FileSystemObject object's GetParentFolderName method, as shown here:

    Dim fso
    Set fso = CreateObject("Scripting.FileSystemObject")
    Path = fso.GetParentFolderName(WScript.ScriptFullName)

As long as Microsoft implements GetParentFolderName correctly, you get the path (independent of the operating system). However, you must use extra memory to create the file system object and expend extra time to execute the method.

## Getting the Current Directory

Microsoft Visual Basic and Microsoft Visual Basic for Applications (VBA) have a function that retrieves the current directory. In a script, the current directory is identical to the directory from which the script is executed, so you can use either the code shown in the previous section or the following statements to retrieve the current directory:

    Dim fso
    Set fso = WScript.CreateObject("Scripting.FileSystemObject")
    ' CurrentDir = fso.GetAbsolutePathName("")
    ' Or use the following syntax:
    CurrentDir = fso.GetAbsolutePathName(".")

In this sequence, the FileSystemObject object retrieves the path by using the GetAbsolutePathName method with the parameter ".".

> NOTE

> CurrentDir.vbs (in the \WSHDevGuide\Chapter14 folder) shows the current directory and the script path in a message box. Alternatively, you can use the GetDir method (which I'm about to explain).

## Setting the Default Folder

WSH doesn't provide a way to set the default directory of a program, but a few workarounds are available. The simplest approach is to put the requested files into the folder that contains the script file. You can then use the GetPath functions (as you've already seen) to locate the path to the current folder.

The second approach is to create a shortcut file, set its execution path and working directory, and then use the Run method to execute the shortcut. The application launched from the shortcut file receives all the parameters set.

The third approach is to create a BAT file that includes cd commands and calls the application. You can then use the Run method to execute the batch program. (You can find details about creating shortcut files and using the Run method in Chapters 7 and 10.)

## Getting the Current Drive Name

You can retrieve the current drive name by using the ScriptFullName property of the WScript object, but this approach is complicated by UNC paths. A much simpler method, which also works for UNC paths, uses the following code:

    Set oFS = WScript.CreateObject("Scripting.FileSystemObject")
    oldDrive = oFS.GetDriveName(WScript.ScriptFullName)

You pass the ScriptFullName property value to the FileSystemObject object's GetDriveName method, and the method returns the name of the current drive, as shown in Figure 14-1.

Figure 14-1 Displaying the name of the current drive (from a UNC path)

> NOTE

> The code shown above always returns the drive from which the script file is launched. You can't change the current drive from WSH using the methods provided by its object model.

## Calculating Date Differences

You can calculate date differences in VBScript by using the DateDiff function. According to the VBScript help, you must specify the interval in the first parameter; the other two parameters are the dates used to calculate the difference, as shown here.

    WScript.Echo DateDiff("d", Now, "1/1/2020") & _
                 " days left to 2020..."

This statement uses the "d" (days) interval to calculate the days left until the year 2020. Now submits the current date, and the third parameter sets a fixed date value.

> NOTE

> The date separator you use depends on the local settings of your operating system.

Figure 14-2 shows a sequence of date differences and displays the days left until a given date. Something went wrong, as you can see in the last line: the date difference is negative.

Figure 14-2 Date differences

Let's take a closer look at the code for calculating date differences. Both the following lines calculate the date difference between now and January 1, 2020:

    MsgBox DateDiff("d", Now, "1/1/2020") & " days left to 2020..."
    MsgBox DateDiff("d", Now, "1/1/20") & " days left to 2020..."

Even though the second statement uses a two-digit year value, 20, both statements return the correct date difference (in days).

However, it's risky to use two-digit dates. The following two statements result in different values:

    MsgBox DateDiff("d", Now, "1/1/2030") & " days left to 2030..."
    MsgBox DateDiff("d", Now, "1/1/30") & " days left to 2030..."

The second statement displays a negative value (as shown in Figure 14-3). The date "1/1/20" causes DateDiff to calculate the days until January 1, 2020, but "1/1/30" causes DateDiff to calculate the days until January 1, 1930.

This situation is the result of the infamous "Y2K bug." Many programs written in the 20th century used two-digit year values. To enable programs to calculate date differences between 19xx and 20xx, Windows uses a bias value for two-digit year values. All values between 0 and 29 are interpreted as the years from 2000 to 2029. Values of 30 to 99 are interpreted as 1930 to 1999. Therefore, it's always good programming style to use four-digit date values in your scripts. You can check this behavior by using the DateTest.vbs file in the \WSHDevGuide\Chapter14 folder.