Tuesday, 07 September 2010
PicoSearch

It's All (nearly) in the Script

This column appeared in the April 2000 edition of EXE. It reviews the key features of the VBScript dialect of Visual Basic, and then examines its usage in the Windows Scripting Host.


I must admit to feeling very fortunate about being the regular columnist for Visual Basic. Not only is Visual Basic the most widely adopted of Microsoft’s developer tools but the core language itself crops up in several places, most notably in Visual Basic for Applications; a technology which third–parties can licence for their own products. This month however I would like to involve another guise of the language: Visual Basic Scripting Edition, also known as VBScript. The language itself is a cut down version of Visual Basic, but the bulk of the constructs are still available and, importantly, it still offers access to ActiveX components. I’ll briefly discuss what differences exist, but frankly this is more a matter of detailing what features are missing. I’ll then move on to discuss the Windows Scripting Host tool, which supports the VBScript language (among others).

VBScript

VBScript is, to all intents and purposes, the same language that we use with the full–blown Visual Basic development tool. Various aspects of the language have, however, been lightened up in order to reduce the implementation overhead. Visually, the most noticeable difference is in the area of declaring variables, in that everything is a variant. Although variants store subtypes of data, such as date, string, integer, long, object, and so on, the actual variable definition is always of this one type. Therefore a variable will always be just declared by name, such as

Dim LoopCount

rather than

Dim LoopCount As Long

Of course it’s not even necessary to make this declaration; if you skip the Option Explicit statement at the top of the script then all variables declarations will be implied by their appearance within the actual code. Other major exclusions from VBScript are:

  1. The Debug object.

  2. The collection and clipboard objects.

  3. The Declare statement (for declaring DLLs).

  4. All traditional Visual Basic file I/O (but you can use FileSystemObjects instead).

  5. All financial functions.

  6. Most of the error handling constructs (On Error Resume, Resume Next, On Error Goto, the undocumented Erl value).

  7. Conditional compilation constants (#Const, #If .. Then .. #Else)

One familiar feature that the most recent implementation of VBScript (version 5) does provide is that of classes, which are declared as shown in listing 1.

Option Explicit
Const Pi = 3.14159

Class AreaCalc

  Public Function GetArea(Radius)
    GetArea = Pi * Radius * Radius
  End Function

End Class

Dim Result
Dim o

Set o = New AreaCalc
Result = o.GetArea(25)
WScript.Echo "The area of this circle is " & Result
Set o = Nothing

Listing 1: VBScript class declaration example

Visual Basic recognises files with a cls extension to contain a class, but because a VBScript component is often encapsulated within a single physical file a new syntax is introduced in the form of Class..End Class. I understand that the Visual Basic development team are apparently considering implementing this syntax into Visual Basic in order to comply with the fact that VBScript is supposed to be a subset of the full–featured language.

Windows Scripting Host (WSH)

For those software developers who were using PCs before the Windows environment really got going there will no doubt be fond memories (er, or not) of MS–DOS batch files; the precursor to scripting. Once the Windows environment became more established there were two approaches to writing routines for administration tasks: continuing to use batch files (with the BAT or CMD extension) or, at the other end of the scale, using full–blown development tools such as Visual Basic to provide EXE applications.

The WSH is a utility that incorporates the best of both worlds. As the name implies it is a facility designed to run scripts, and as an added bonus it is language–independent too. For the purposes of this discussion we will continue to make use of VBScript, but it’s worth noting here that it can also host other languages such as Jscript and, if you have the relevant third–party technologies, Perl, Python, and Rexx. The major improvement over batch files however is the support for ActiveX technology, which of course opens up the language to interfacing with a wide range of software components. Furthermore it also brings its own object model to the party, which we will take a look at in a moment.

VBScript files are conventionally given a vbs extension and JScript files are denoted by js. The Windows namespace is familiar with these extensions and so associates them with wscript.exe; the Windows–based version of the WSH runtime program. Therefore, for example, double–clicking a file with a vbs extension will cause the WSH program to load up and then run the script within the file. To illustrate the most fundamental illustration of this in time–honoured fashion, if you type

MsgBox "Hello world"

into a blank file, save it as hello.vbs, and then double–click the resulting file from the Windows Explorer you will see the expected dialog box. No need for a development environment, compiler, or associated installation of runtime files! Aside from the Windows–based wscript.exe there is also a Win32 console–based version, in this case called cscript.exe.

When a WSH script is executed an internal object model called WScript is automatically instantiated and made available. Apart from providing root level properties such as the name and path of the current script and the current WSH version number it also exposes a method called Echo which is actually more appropriate than the MsgBox example I cited above. If there is any chance that the script will be run in console mode then you should always use WScript.Echo instead of MsgBox because it will display a standard line of text within the console window if it is being run in this mode, but if it is being run in Windows mode (i.e. via wscript.exe) then a standard message box will be displayed instead.

The root object is also the path to a couple of subordinate objects that provide access to the network and shell areas of Windows itself. For example, you can create an instance of the Network object in the usual way, i.e.:

Set oNetwork = CreateObject("WScript.Network")

and you can then obtain or set information as required, such as

WScript.Echo oNetwork.ComputerName

The scope of the facilities made available by this object is perhaps illustrated by the AddWindowsPrinterConnection method which will allow you to dynamically add a new printer connection to Windows. Similarly, the underlying shell object allows to you create desktop shortcuts, obtain and expand environment strings, write data to the event log, read from and write to the registry, and run other processes. For example, to obtain the actual full path to the current users desktop area, you would first obtain a reference to a Shell object and then call the SpecialFolders function:

Dim oShell
Dim sPath
Set oShell = CreateObject("WScript.Shell")
sPath = oShell.SpecialFolders("Desktop")

WSH 2.0

The initial version 1.0 of WSH was introduced with Windows 98 and also with the Windows NT 4 Option Pack. Windows 2000 introduces version 2.0, although the application logo message that is displayed by cscript.exe when you are in a console window would have you believe that you are using version 5.1. This confusion aside, WSH 2.0 includes a lot of new features that certainly improve upon the previous version.

The most fundamental change to the specification is the addition of an XML–based file type that has the extension .wsf (short for Windows Script File). Didn’t I say last month that we would be seeing a lot of XML this year? The incorporation of the XML language provides a new framework for the script file, allowing for a greater scope of definition of each logical entity within the file. Although vbs and js files are still supported for backward–compatibility, a wsf file incorporates the new concepts of Jobs and Packages. A Job element is the logical grouping of a series of tasks into a single batch; this is pretty much equivalent to a single vbs file. A job can consist of multiple blocks of code which are each identified by the XML <script> tag. By virtue of the language attribute of this tag it is also quite easy to mix different languages within the same job. A set of jobs is referred to as a Package, which is really just a means of identifying the scope of the jobs within the wsf file. If there is more than one job within a wsf file then it is necessary to embed them all within a pair of <package> tags, otherwise the presence of this tag is optional. Listing 2 illustrates the overall flow that exists within a wsf file that includes multiple jobs.

<package>
  <job id="job1">
    <script language="VBScript">
      WScript.Echo "Running a VBScript item..."
    </script>
  </job>
    <job id="job2">
    <script language="JScript">
      WScript.Echo("Running a JScript item...");
    </script>
  </job>
</package>

Listing 2: .wsf file using jobs and multiple languages

By default only the first job in a file is executed, but there is a command line option for both of the hosting applications that allow you to specify which of the jobs should be run – the //Job:xxxx option. Therefore if you run the script in listing 2 by double–clicking from the Windows Explorer you will only see the first message “Running a VBScript item…”. However, if you open the Run dialog from the Windows Start menu and specify something like

Wscript.exe c:\somedir\myjobs.wsf //Job:job2

Then you will instead see the “Running a JScript item…” message.

One inevitable improvement is the addition of support for include files. As with other languages this allows for libraries of common code to be maintained and called as necessary, but because this referencing of other files is dependent upon the XML tag it is only available to wsf files. The actual reference is achieved by modifying the <script> tag to include an src reference to an external file, as in

<script language="VBScript" src="mylib.vbs"/>

As a quick aside, note the use of the trailing slash in the above definition. This is an XML shortcut convention called the empty element tag that denotes the closing of the section opened by the preceding ‘<’ character.

The power that the WSH gives to developers and administrators alike is a major improvement upon the previous batch file concept, and WSH 2.0 in Windows 2000 significantly strengthens the technology even further. For administrators and network support staff the additional inclusion of Windows Management Instrumentation (see separate panel for overview) – which is callable from wsf scripts because of its ActiveX interface – provides a rich collection of key system information. Developers too will appreciate its power both for writing components for formal systems development, but also for writing their own quick support/configuration jobs. Further information on this technology can be obtained from the Microsoft site at http://msdn.microsoft.com/scripting. For the serious enthusiast there is also a book called Windows Script Host Programmer’s Reference written by Dino Esposito (Wrox Press, ISBN 1–861002–65–3).


The article also included a sidebar outlining the basics of Windows Management Instrumentation (WMI)

WMI is the specific Microsoft implementation of an emerging industry standard known as Web–Based Enterprise Management (WBEM). The concept is that management information about a computer installation can be accessed in a uniform manner. Examples of such information are memory usage, installed applications, hardware specifications, and so on. A WMI programming interface allows developers to write programs that retrieve information about, or manipulate as appropriate, the various aspects of a computer installation using a SQL statements. Logical areas of functionality are implemented as providers, of which a core set are supplied by the WMI SDK. For example the event log provider allows an application to receive notification of Windows events, and also provides access to the event log data itself. Third–party companies can provide their own providers for their own products.

WMI is supported on Windows NT4 service pack 4 and above (including Windows 2000), and Windows 95 SR2 and Windows 98.

Copyright ©2002 Jon Perkins I, Jon Michael Perkins, hereby assert and give notice of my right under section 77 of the Copyright, Designs, and Patents Act 1988 to be identified as the author of the foregoing article.