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
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
In this article, I discuss some details of the
As I mentioned, you can document a .wsf script's supported arguments in its
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
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
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:
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