Skip navigation

Use WSC to Write Reusable Code

Downloads
16166.zip

Building a library of reusable code is helpful because you don’t have to keep reinventing the wheel each time you automate a new task. If you want to use a scripting language to write reusable code, one option is to use Windows Script Components—WSC. (You can write reusable code several ways. To learn about the various options, see the sidebar "Is WSC Right for You?")

What Is WSC?


WSC is primarily a feature of Windows 2000 and Microsoft IIS 5.0, but you can install WSC in earlier Windows platforms as an add-on. To install WSC, you need to install either Microsoft Internet Explorer (IE) 5.0 or later or Windows Script (WS) 5.5, which contains WSC. You can download WS 5.5 from http://www.microsoft.com/msdownload/vbscript/scripting.asp. Although WSC is a native object of IE 4.0 and Windows 98, Win98’s WSC (formerly called XML Scriptlets) supports a slightly different syntax and isn’t fully compatible with Win2K’s WSC. In this article, I cover the Win2K syntax. For information about the Win98 syntax, see the Microsoft Developer Network (MSDN) article "Writing COM Objects with Scripting Languages".

A WSC object is basically a COM object made of scripting code. The WSC object works like a COM object. However, the WSC object isn’t a compiled binary file like most COM objects but rather an XML file that exposes a list of properties and methods that you implement through scripting code. You can use any scripting language to implement these methods and properties, as long as you run the code on a Windows-compliant scripting engine. IE 4.0 and later has such an engine for VBScript and JScript. Third-party engines for languages such as Perl, Rexx, and Python are available on the Internet.

To write a WSC object, you need to create an XML file that complies with a particular schema. This XML file has a .wsc extension and contains three types of information:

  • The object’s description, which consists of the registration, programmatic identifier (ProgID), class identifier (CLSID), and version number
  • The programming interface, which consists of the object’s methods, properties, and events
  • The scripting code for each method, property, and event

A system-provided runtime engine processes the WSC object’s XML source code. You might be wondering how a COM-aware client can talk to a text-based file and treat that file like a compiled binary COM object. The executable modules (i.e., .dll or .exe files) that implement COM objects are pieces of compiled binary code that clients recognize. The executable module that implements WSC objects (i.e., the WSC runtime engine, which is a system file called scrobj.dll) is also a piece of compiled binary code that clients recognize. Clients can't perceive the difference between a WSC and COM object, but they recognize the appropriate compiled binary module when they attempt to instantiate a WSC or COM object.

When a client instantiates a WSC object, the client goes through the usual series of actions to instantiate a COM object. The client reads the path to the executable that renders the object (i.e., the WSC runtime engine) and starts talking to that engine. The engine acts like a proxy and makes the WSC object’s methods and properties available to clients. The engine resolves any method or property call in the scripting code.

Creating a WSC Object


Listing 1 presents a .wsc file that creates a simple WSC object that you can use to display a message box. The file includes XML tags that define the WSC object and its behavior. Because XML files are similar to HTML files, the XML tags are similar to HTML tags. Let's analyze the XML source code in detail.

The first line in Listing 1 declares the XML document compliant with version 1.0 of the XML standard. This directive doesn’t directly affect how the system treats the .wsc file.

The root tag in the second line and in the last line in Listing 1 wraps all the information for the WSC object. A .wsc file can contain more than one object. If you define more than one object in a .wsc file, you must change the root tag to . (You can also use as the root tag if you're defining just one object in the file.) In addition, you must associate a component ID with the tag for each object in the file. Listing 2 shows how you set up a .wsc file for two objects.

As I mentioned earlier, a .wsc file contains three types of information: the WSC object’s description, programming interface, and scripting code. You describe the object with the tag. You declare the object’s programming interface (i.e., the object’s methods and properties) with the tag. You define the object’s methods and properties with the <script&gt: tag.

The Tag


Listing 1 contains the minimal content for the tag. In this case, you’re specifying only the object’s progID attribute, which is MyComp.Hello. You should consider progID a mandatory attribute (more on this point shortly). You can also specify three optional attributes: description, version, and classid. The description attribute lets you specify a description of the object's behavior. The version attribute lets you specify the object’s version number. (The default is 1.0.) The classid attribute lets you assign a 128-bit CLSID to the newly created object. The code in Listing 3 shows an example of a fully featured tag.

If you're familiar with the COM fundamentals, you know that a generic COM object must have a 128-bit CLSID but the progID is optional. Because a WSC object is a COM object, the progID is theoretically optional. However, in practice, a progID is necessary because you’ll be using the WSC object as a COM automation object (i.e., a COM object that exposes methods and properties so that other applications can programmatically drive it). Without a progID, the WSC object is unusable because the CreateObject function needs the progID to instantiate the object for further use. Instead of omitting the progID, you can omit the CLSID in the tag because the WSC runtime engine can generate the CLSID on the fly.

The Tag


To expose their functionality, COM objects implement interfaces. All COM objects implement the basic IUnknown interface and make this interface available to callers. In addition, COM objects can implement and make available other interfaces. A WSC object can implement a limited number of interfaces. These interfaces fall into three groups:

  • Interfaces needed for automation and event handling (i.e., automation interfaces)
  • Interfaces needed for Active Server Pages (ASP)
  • Interfaces needed for IE 5.0 behaviors

For now, I concentrate on how to create automation-interface WSC objects. I cover the ASP and IE interfaces later.

The WSC syntax doesn’t dictate that WSC objects implement an automation interface. However, in practice, any WSC object must implement this interface. To declare the automation interface, you use the tag. These declarations point to the methods, properties, and events that you define with the <script&gt: tag.

The tag declares the object’s methods and the properties, plus any events the object can raise under certain circumstances. You use the , , and elements to declare them. All three elements have an attribute called name, which represents the element’s formal name. The and elements can take parameters, which you specify with the tag. The tag’s name attribute declares the parameter’s formal name. You can specify as many tags as needed.

You can assign the elements read and write privileges with the Get and Put functions, respectively. If you want a property to have read privileges, you declare . If you want a property to have write privileges, you declare . If you want a property to have read and write privileges, you declare both and , as callout A in Listing 1 shows. In this code, the MyComp.Hello object’s block declares both read and write privileges for the property named Title, which will contain the message box’s title. If you want the Title property to have read/write or not privileges, you can use code such as

<property name="Title">
	<get/> <!-- omit if write-only -->
	<put/>	<!-- omit if read-only -->
</property>

In addition to declaring the Title property and its privileges, the block at callout A declares one method called Say. The Say method takes one parameter named text, which will contain the text that the message box will display.

The <script&gt: Tag


After you declare an WSC object’s methods, properties, and events, you need to define them in a <script&gt: block. For the MyComp.Hello object, you need to define the Say method and the Get and Put functions, as callout B in Listing 1 shows. However, before you can include these definitions, you first need to declare and initialize internal variable names for all the properties you declared in the block. Each property needs an internal variable to hold its value. You can give any name to the internal variable as long as you declare and initialize it. For example, the internal variable name for the MyComp.Hello object’s Title property is m_Title. The code

m_Title = ""

initializes that variable to an empty string.

With the properties’ internal variable names declared and initialized, you can include the definitions in the <script&gt: block. As callout B in Listing 1 shows, you can use the Function statement to define the methods and functions. (For information about how to use the Function statement, see "Understanding VBScript: Built-In and User-Defined Functions," October 1999.)

When most people define the Get and Put functions, they typically use the default names, but you can specify custom names. The default names for the Get and Put functions are get_Xxxx and put_Xxxx, where Xxxx is the name of the property. For example, the default Get and Put function names for the Title property are get_Title and put_Title.

To change the default names, you can use the Get and Put functions’ internalname attribute. Suppose you want to use the custom names of GetTitle and PutTitle instead of get_Title and put_Title. Instead of declaring <get/> and <put/> in the <public> block, you use the code

<property name="Title">
	<get internalname="GetTitle" />
	<put internalname="PutTitle" /> 
</property>

Then, in the <script&gt: block, you use the custom names instead of the standard names:

Function GetTitle()
	GetTitle = m_Title
End Function

Function PutTitle(newTitle)
	m_Title = newTitle
End Function

With these changes in place, the WSC runtime engine will search for the custom names when it accesses the Title property for reading and writing.

When writing the scripting code for a WSC object, you need to keep in mind that you’re writing code within an XML file. Certain characters in the scripting language might also have special meanings in XML. For example, the ampersand (&) and caret (

<script language="VBScript">
<!\[CDATA\[

' Scripting code goes here.

\]\]>
</script>

The scripting language’s parser engine then implements the methods and properties you define in the <script&gt: block. You aren’t restricted to using only one scripting language. The only reason why you might not want to mix languages is that keeping more parser engines in memory might affect overall performance.

Testing a WSC Object


Before you use a WSC object in production, you need to test it in a nonproduction environment. As with any other COM object, you must register a WSC object before you test and use it. You can register a WSC object two ways:

  1. Right-click the .wsc file, then select the Register menu command.
  2. Start the regsvr32.exe utility from the Run prompt or the MS-DOS console. You must pass the .wsc file’s fully qualified path to the utility.

During the registration process, the WSC runtime engine generates a CLSID for the object if you didn’t include that information in the tag.

You use a WSC object in code the same way you use any other COM automation object. You begin by using the CreateObject function to create an instance of the WSC object. For example, to instantiate the MyComp.Hello object, you can use the code

set obj = CreateObject("MyComp.Hello")

The client then talks to the WSC runtime engine, which, in turn, loads and interprets the associated .wsc file to expose the object’s methods and properties. You can now call any of the object’s methods or properties from any COM-aware client. For example, to call the MyComp.Hello object’s Say method and Title property, you can use the code

obj.Say "Hello world!"
obj.Title = "Hi"
obj.Say "Hello World again!"

Beyond the Automation Interface


Automation-interface WSC objects are only one type of WSC object you can create. You can create two more types of WSC objects: server-side objects that access the ASP object model and client-side objects that access the IE 5.0's Dynamic HTML (DHTML) object model. Although you can create a WSC object that has only an ASP interface or only an IE interface, you probably wouldn’t want to. Without the automation interface to provide methods and properties, the object would be unusable. Thus, here’s a look at how you can add an ASP or IE interface to a WSC object that already has an automation interface. (You can’t create a WSC object that has both an ASP and IE interface.)

Adding an ASP interface. With an ASP interface, your WSC object can access the Request, Response, Server, and other objects in the ASP object model. As a result, your WSC object can accomplish certain tasks within the IIS environment, such as reading parameters that browsers send and manipulating session information and response text in a client page.

To add an ASP interface to an automation-interface WSC object, you need to include the extra line

The best practice is to place this line before the <script&gt: block. This line tells the WSC runtime engine to obtain a reference to the ASP objects and add that reference to the script context. (The script context is an area of the memory that stores pointers to all the objects that the code can use.) After you declare that you want to access ASP objects, you can safely make calls to them.

Adding an IE interface. DHTML objects are special IE 5.0 COM objects that customize the behavior of HTML tags within a page. You can use DHTML objects to personalize the way in which one tag or all tags of a certain type work within a page. For example, you can use a DHTML object to automatically highlight links when a mouse passes over them without having to flood the page with scripting code. Basically, the DHTML object already contains all the scripting code for that behavior. You simply assign that behavior to any tag of that class as a Cascading Style Sheets (CSS) style.

To add an IE interface to an automation-interface WSC object, you need to include the extra line

Once again, the best practice is to place this line before the <script&gt: block. This line tells the WSC runtime engine to obtain a reference to the DHTML objects and add that reference to the script context.

Recommended Tools


Now that you understand the WSC basics, you might be interested in a couple of handy tools for WSC. These tools are the Windows Script Component Wizard and SAPIEN Technologies’ PrimalSCRIPT 2.0.

The Windows Script Component Wizard is a Microsoft tool that automates the process of creating a .wsc file. You just supply the needed information in a six-step process. After the wizard finishes, you have a working .wsc file that you can customize. In his column "Scripting Solutions with WSH and COM: Using WSC to Build a Progress Bar Dialog Box, Part 2" (October 2000), Alistair G. Lowe-Norris discusses how to use the wizard.

WS 5.5 includes the Windows Script Component Wizard, but you can download it separately from the Microsoft Scripting Web site. Go to http://msdn.microsoft.com/scripting/default.htm?/scripting/scriptlets/default.htm. In the menu on the right, click Downloads. The page that appears contains a link to download the wizard. The menu on the left also has a Documentation link that brings up a page with links to the WSC language reference and other supporting documentation.

PrimalSCRIPT 2.0 is a fully featured Windows Script Host (WSH) editor that specifically supports WSC. A free 30-day trial version is available (http://www.sapien.com/products.htm).

With these tools and a basic knowledge of WSC, you can start creating a library of reusable code. This library will save you much time and effort.

Hide comments

Comments

  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Publish