Mr. Script

Scripting Serendipity

Finding out that .WSF scripts—based on XML—allow you to declare just about anything can be a flexible timesaver.

Serendipity. The English author Horace Walpole coined the word in a letter dated Jan. 28, 1754. It’s defined as an accidental, but fortunate, discovery. Were I to equate the word to scripting, I might call it a pleasant byproduct of a particular feature—one that might very well have slipped by unnoticed and unused. Scripts in the .WSF format are based on XML. XML allows you to declare virtually anything via an appropriate tag—things like objects. Serendipity! The ease with which this is accomplished only adds to its value. You may remember I used this technique before when I referenced objects in my Windows Script Components (WSCs). Yes, just as .WSF scripts share similarities in format with WSCs, they also include the ability to place references to all sorts of objects—and the syntax is the same.

<?xml version=”1.0”?>
<package>
<comment>

Objects.wsf
This script demonstrates the ability to declare objects
For a particular job within .WSF files

</comment>
<job id="Count">
<object id=”objFSO”progid=
     "Scripting.FileSystemObject"/>
<script language="VBScript">
<![CDATA[

msgbox objFSO.Drives.Count

]]>

</script>
</job>
</package>

This script creates a reference to the FileSystemObject and displays the current number of drives known to the operating system (including mapped network drives). As with everything in the world of scripting, there are rules for using the <object> tag:

  • Each object must be declared inside the <job> that will use it. You can’t declare objects for an entire <package>, nor use an object declared inside another <job>.
  • The tag’s usage is <object id="id" progid="progid">
  • The id for the object is the name of the variable you’ll use to reference it within the script. Use this attribute in place of a Dim statement. In fact, if you include a Dim statement for the included object, it’ll reset the variable to “empty” and break your script.
  • The progid of the object is in the standard libraryname.classname format. If you need help figuring out this nomenclature for a particular DLL, simply view it using our old, trusty pal, XRay.exe.

Using the <object> tag eliminates the need to execute the following commands:

Dim objMyObject
Set objMyObject=CreateObject("Library.Class")

What’s The Hubbub… Bub?
“Hmmph! So what? So, we type only one line instead of two. Big deal!”

Well, the benefits of declaring objects in this manner reach a bit further than that. By declaring the objects outside the script code, we gain the advantage of what I call “pseudo-early binding.” As you know, VBScript can only create objects using late binding—the objects are created as needed, at runtime. By declaring these objects using the <object> tag, memory is allocated while the script is loading, rather than during script execution. Depending on how heavily you rely on objects (I use them a lot), this can really speed up your scripts.

Speed is good, but there are even greater benefits. By placing the object declarations at the <job> level, rather than the <script> level, these objects are available to any and all individual scripts within a job.

<?xml version="1.0"?>
<package>
<comment>

Objects2.wsf
Demonstrates how objects are available to all scripts
in the job

</comment>

<job id="FSO">
<object id="objFSO" progid="Scripting.FileSystemObject"/>
<object id="objShell" progid="WScript.Shell"/>
<script language="VBScript">
<![CDATA[

msgbox objFSO.Drives.Count

]]>

</script>
<script language=
”JScript”>
<![CDATA[

var bDriveExists;
bDriveExists=objFSO.DriveExists("C:");
objShell.Popup(bDriveExists);

]]>

</script>
</job>
</package>

In this script, I have declared two objects: the FileSystemObject and the WSHShell object. (The WSHShell objects allow me to display a pop-up box in the JScript portion of the script. JScript doesn’t support msgbox.) Both scripts were able to access data from the objects.

But Wait, It Gets Better!
Looking back on your homework, we created a .WSF script with multiple jobs. Cool concept: One file, lots of scripts inside. Each job could contain multiple scripts, but we really didn’t have any way to get them to work together. Normally, in multilanguage scripts, all declared variables are reset after the </script> tag is read. This meant that every time we switched from VBScript to JScript we were basically starting from scratch. Not so when using the <object> tag. Because any script inside the <job> can access these objects, we have a perfect opportunity to persist data between scripts.

How, you ask? Go back to those wonders of modern technology: Windows Script Components! Simply create a WSC for persisting data (i.e. create a component with a bunch of properties—no methods are necessary). Once your component is registered, you can reference it via the <object> tag, just like any other object. Voila! A ready-made data-persister (probably not really a word, but who cares?)

Here’s an example of a WSC created to persist a single value:

<?xml version=”1.0”?>
<component>

<registration
     description=
"MyDataComponent"
     progid="MyDataComponent.WSC"
     version="1.00"
     classid="{0ed4d22b-6bc6-4f0a-8981-328da463234b}"
>
</registration>

<public>
     <property name=
"MyProp1"/>
</public>

</component>


<text>

And here’s the script to use it:

<?xml version=”1.0”?>
<package>
<comment>

DataPersist.wsf
Demonstrates how objects can persist data
To all scripts in the job

</comment>

<job id=
"MDC">
<object id=
"objMDC" progid="MyDataComponent.WSC"/>
<script language=
"VBScript">
<![CDATA[

objMDC.MyProp1="Hello World!"

]]>
</script>
<script language=
"JScript">
<![CDATA[

WScript.Echo(objMDC.MyProp1);


]]>
</script>
</job>
</package>

Not bad, eh? All this functionality is made possible by just the <object> tag! Next month, I’m going to take a look at some of the other tags you can use in .WSF files to make things really interesting.

About the Author

Chris Brooke, MCSE, is a contributing editor for Redmond magazine and director of enterprise technology for ComponentSource. He specializes in development, integration services and network/Internet administration. Send questions or your favorite scripts to [email protected].

comments powered by Disqus
Most   Popular