Subscribe to Windows IT Pro
June 14, 2004 12:00 AM

Automated Argument Validation

Police the WSH command line
Windows IT Pro
InstantDoc ID #42735
Rating: (0)
Downloads
42735.zip

3. Use argument validation in your scripts. Listing 2 shows tee.wsf, which uses wshargex.wsc to validate arguments. Tee.wsf functions like the UNIX tee command, which reads characters from a command console's standard input stream and writes them to the standard output as well as to one or more files. Instead of writing a few lines of code to check the command-line arguments from the user, tee.wsf just passes them to the component for validation.

To use standard input and output streams, you must run the script with CScript explicitly. Just having CScript set as your default script host isn't enough to redirect the console input stream. (For a simplifying workaround, see "Convert WSH Scripts into Console Tools," March 2004, InstantDoc ID 41501.) You can use this workaround for any situation in which you want to look at the results of a command on screen and send them to a file at the same time.

The code at callout A in Listing 2 shows the script's argument specifications. I specify only two arguments; by running the script with the /? argument (a default in WSH), you can get the argument Help screen to display automatically. The first specification, the named argument "A", tells tee.wsf to append to files instead of overwriting them. The argument type is simple, meaning that it should have no data. The second specification is an unnamed argument description called "filename" in the displayed Help text. This argument is the path to one or more files to which the console will send output. The user must specify at least one file.

The code at callout B begins the validation. First, I use the standard CreateObject command to set argEx as a reference to the WshArgument.Extensions class from wshargex.wsc.

Next, I give argEx a reference to WScript by setting its Wsh object to the internal WScript reference available to all WSH-hosted scripts. ArgEx needs this reference so that it can look up information such as the path to the script host, the path to itself, and the script argument collections.

As I mentioned earlier, the user must run the script with CScript, so the third line in callout B sets argEx's RequireCScript property to True. This setting makes validation fail if the tee.wsf script runs from the wrong host. If you try running tee.wsf with wscript.exe as the host, you'll see that tee.wsf automatically displays its Help text, then exits. If you try to supply a filepath as a value to the A argument (which must have no value), as in

cscript tee.wsf /a:c:\netstat.txt

tee.wsf displays Help and exits. If you run tee.wsf with no arguments, as in

cscript tee.wsf

tee.wsf displays Help and exits. If you run tee.wsf with one or more filenames, as in

cscript tee.wsf 1.txt 2.txt

the script just displays a blinking cursor on screen and echoes back everything you type until you press Ctrl+C. This behavior is expected because CScript is using your keyboard for standard input. When you press Ctrl+C, you might see an application error message; just press Enter to continue.

Next, tee.wsf calls the argument validation code in wshargex.wsc so that it can check the arguments. The validation (which ensures the arguments are the correct type and the host is appropriate) automatically occurs in the lines of code in callout B that I've described. ArgEx has several other properties that you might need to set for special behavior in a script; they're commented out in tee.wsf because it doesn't need them:

JobId. If you typically write .wsf files that contain multiple jobs, you need to specify the value of the id attribute from the .wsf file's <job> tag. Each job has to have its own <runtime> element, so you need to let the component know which job it's checking. To avoid worrying about this value, write .wsf files that contain only one job.

TraceExecution. TraceExecution works only when you use CScript as the host application. Setting this property to True tells argEx to echo tracing information as it runs. If you can't make some command-line options work, the trace will help you determine which argument caused argEx to fail and why.

ContinueOnFailure. If you set ContinueOnFailure to True, argEx will continue to check arguments even after it finds an invalid one. To determine whether validation failed, you can look at the return value of ValidateArguments or you can query the IsValid property after calling ValidateArguments.

AllowLooseTyping. This property turns off the type checking of named arguments. If you want to let users ignore the argument specification type of the named elements, set this property to True.

ExitErrorLevel. By default, if wshargex.wsc exits because of an argument validation error, the console error level returned is 2. You can use ExitErrorLevel to set the error level for failures to another value.

As I mentioned previously, I commented out these properties. If you want to set them, you need to do so before tee.wsf calls ValidateArguments, as callout B shows.

Where to Go from Here
As mundane as the topic of argument validation is, I actually found myself getting pretty excited when I saw how to automate it. When I use argument validation in this way, it frees me from worrying about a cumbersome and boring detail in scripting. Furthermore, it transforms Help text from an afterthought to a contract between the scripter and the script user—and the script itself will comply with it. If you want a script argument to work, you absolutely must write the argument specification.

You can see the potential of contracts like this by looking at what contractual interfaces did for programming a few years ago. After Microsoft introduced COM objects into Windows programming, they quickly became black-box tools. Their interfaces describe what kind of data they need and prevent using any other data types. Although this approach requires more programming discipline, the effect is that people no longer need to worry about the internals of a program element. They can look at its interface and be sure that everything they need to know about the data supplied to the component is right there. Checking arguments with my .wsf argument validation component provides the same guarantee that what you say the script wants is what it really expects; the simpler coding is just a fringe benefit.

Related Content:

ARTICLE TOOLS

Comments
    There are no comments to display. Be the first one!
You must log on before posting a comment.

Are you a new visitor? Register Here

advertisement

advertisement

Windows is a trademark of the Microsoft group of companies. Windows IT Pro is used by Penton Media Inc. under license from owner.