Downloads
42735.zip

Windows Script Host (WSH) provides two useful but potentially confusing tools for working with command-line arguments: the WshArguments object, which lets scripters easily read supplied arguments and their types and values, and (specifically in Windows Script File—.wsf—files) the XML element, which automates Help text generation. (A .wsf file uses an XML structure to add helper elements to a script; for easy identification, I refer to these helper elements by their tag names, which are simply the element names enclosed in the angle brackets—<>—used to delimit tags.) It's easy to confuse these tools' characteristics. Scripters often assume that the element's and elements validate user-supplied arguments, when in reality these elements simply give you nicely formatted Help text. As Bob Wells discusses in "Rem: Relating the WSH 5.6 Element to Mandatory Arguments," October 2002, InstantDoc ID 26363, the elements don't validate user-supplied arguments. In other words, even though the and elements in a .wsf script explicitly describe argument constraints (e.g., what's required, what's optional, what kind of values arguments should have, the number of arguments), you have to write the code to validate those arguments.

Although WSH simplifies validation, you still have room for mistakes and extra work. You might modify arguments used within a script but forget to modify the relevant Help descriptions. You'll probably validate arguments a little differently in each script, and you'll waste time writing similar code multiple times. Fortunately, you can use Microsoft XML components to parse the tag contents fairly easily, so you can write code that will automatically validate user-supplied arguments against the runtime specification.

In this article, I discuss some details of the element of .wsf scripts and the WshArguments collection and demonstrate (with the code in Listing 1) that WSH doesn't validate user arguments against the and elements. I then walk you through using a Windows Script Components (.wsc) component that I wrote to automate .wsf argument validation. To demonstrate the component, I use a WSH script called tee.wsf, which reads characters from a command console's standard input stream and writes them to the standard output and to one or more files. At the end of the exercise, you'll know how to add as few as four lines to your scripts to automate argument validation using my component. You'll also have a handy utility for use with other scripts.

The Element and the WshArguments Collection
As I mentioned, you can document a .wsf script's supported arguments in its section. (See http://msdn.microsoft.com/library/en-us/script56/html/wslrfruntimeelement.asp for more details about the element.) A user can run the script with the command-line argument /? to display the Help text. Alternatively, the script can call the WScript.Arguments.ShowUsage method. I refer to the section as the arguments specification because it's a construction that tells users the command-line requirements they need to meet to run the script.

The WshArguments collection, in contrast, tells you inside a script what arguments the user actually used. For detailed information about the WshArguments collection, go to http:// msdn.microsoft.com /library/en-us/script56/html/wsobjwsharguments.asp.

The Problem: Unvalidated Arguments
To understand the problem of WSH not validating arguments, look at the dummy script in Listing 1. If you save that script with a .wsf extension, then run the script from the command line with the /? parameter, you'll see the following Help text:

listing1.wsf /O\[+|-\]
  /C:value file1 \[file2...\]

For those who aren't familiar with the syntax for command-line arguments, square brackets (\[\]) denote optional items. The only exception is that items inside square brackets and separated by a pipe (|) symbol represent a choice that the user must make: In the command above, the user must use /O+ or /O-, he or she can't just use /O. Anything not enclosed in brackets is required. In other words, according to the Help text, the two simplest command lines valid for this script are:

listing1.wsf /O+ /C:value file1

and

listing1.wsf /O- /C:value file1

However, the script will run with any command-line arguments the user gives it because the argument specification has no ability to enforce any usage rules the Help text sets forth.

The Solution: A Validation Component
The simplest way to tie Help text display and argument validation together is to write code that automatically analyzes the XML elements in the section, then tests the user-supplied arguments to ensure they match the XML description. I wrote the wshargex.wsc component, which Web Listing 1 shows, to do just that. To automate validation, you need to install wshargex.wsc, make sure your scripts are written as XML-compliant .wsf files, and call the component within your scripts to perform validation.

1. Install wshargex.wsc. Make sure that you have WSH 5.6 or later—you need it to use the Named and UnNamed arguments as separate collections in a script. In Windows Explorer, right-click a .wsc component and select Register. If the .wsc component is valid, you'll see a message similar to DllRegisterServer and DllInstall in C:\Windows\System32\scrobj.dll succeeded. If you need to register wshargex.wsc from a command line, you can use the following command:

regsvr32 /s /i:"full-wsc-path"
  %systemroot%\system32  scrobj.dll

where full-wsc-path is the path to wshargex.wsc on your system.

The /s switch prevents regsvr32 from displaying a dialog box (regsvr32 still returns an error to the command line if registration fails). Make sure you register a permanent local copy of the component; registration tells Windows where to find the component, and if you try to use the component from a network location, it might not be available later.

2. Write your .wsf scripts as XML code. The WSH documentation includes details about how to write XML scripts; see "Script Component Files and XML Conformance" (http://msdn.microsoft.com/library/en-us/script56/html/letxml.asp) for the details. Despite the name, the discussion applies to .wsf files as well as .wsc components.

At a bare minimum, the first line of your .wsf file must be

To allow extended European characters (probably a good idea), you should also specify a wider character set. I typically use the following as my first .wsf line:

  encoding="ISO-8859-1"?>

Last, you should use CDATA tags to "hide" your script elements, as I show here and in the listings:

The sequence as literal characters. If you don't use the CDATA tag, the XML parser actually parses special characters such as the angle brackets and the ampersand (&) instead of leaving them alone as script characters. You can use the CDATA tag in any , , ,