Scala - Digital Signage Software [Logo]
Languages: EnglishGermanPolishJapaneseNorwegianFrench
  Markets Products Partners Services Support About Us  
Scala Support Scala Celebrates 20 Years of Innovation and Leadership

Scala - Windows Script Host

An introduction to Windows Script Host for Scala InfoChannel 3.

* This area of the Website is being presented as one long page for easy printing. You can also browse this area of the Website as shorter webpages for easy reading. Visit:  Windows Script Host.


Jun 25, 2004: A quick introduction to my writing style

“I believe that the best way to learn is to teach. And I believe in building up projects in small, very well documented baby steps.”Welcome to my first advice column on the Scala Website. This is a quick introduction before I launch into code. I believe that the best way to learn is to teach. And I believe in building up projects in small, very well documented baby steps. You will find almost the entire body of my programs repeated from page to page, with perhaps a few lines of code added and highlighted and described. This baby-step build-up results in tutorials with lots of pages, but works very well both in helping me think through a problem, and documenting "process" in a way that I think is highly useful and rarely found on the Internet.


Jun 26, 2004: The Windows Script Host and InfoChannel 3

“Scripting languages are generally easier, have a lower learning curve, and take less of a commitment of time than "real" programming, making them ideal for simple tasks.”I am a big fan of the scripting approach to programming, especially in how it can make a programmer out of a non-programmer. Windows Scripting is remarkably similar whether you are programming for the Web, system administration, or InfoChannel, and it is much easier to start than you might imagine. But first a few words of background.

Without delving into a whole history of scripting versus "real" programming, it is sufficient to say that scripting languages are generally easier, have a lower learning curve, and take less of a commitment of time than "real" programming, making them ideal for simple tasks. One might be tempted to call the process of scripting "quick and dirty" programming, but it doesn't have to be dirty at all, as you will learn here. Scripts can be written very cleanly, leaving just the benefit of being quick.

In contrast, Microsoft's new programming platform, .NET, will receive much attention in the coming years. It is a sweeping new programming platform designed to be decoupled from the underlying hardware, allowing portability of program code. And it comes free with Windows, allowing you to write faster compiled program code that has more access to the system. It would appear to be a replacement for scripting. However, it is a full-fledged event driven object oriented programming environment that requires hitting the books in a way that scripting doesn't. Scripting therefore remains an attractive option for those who wish to be productive quickly on small projects, and do not need the benefits of object-oriented programming. I often equate scripting to sculpture, with each small self-contained project being chisel strike. A more traditional programmer might be said to work more like a music composer, coordinating many independent complex parts.

Windows Scripts are most commonly executed in two ways: Active Server Pages (ASP) for the Web and the Windows Script Host (WSH) for system administration. Microsoft's defacto standard language for WSH is Visual Basic Scripting Edition (VBScript), but it also natively supports JavaScript, and has hooks to support other languages. Buy supporting and sharing variables with the Windows Script Host, InfoChannel gains the ability to interact with a wide array information systems using a popular and well documented mechanism, and offers Scala Developers the ability to tie in new functionality programmed in the language of their choice.

“How this extends InfoChannel's capabilities, and the ways in which this can be used by the VAR to design new solutions around InfoChannel and pursue new opportunities is simply staggering.”Most people who get familiar with Windows Scripting do so with the VBScript language, and usually through Web programming in ASP. But it takes nothing more than Notepad to write scripts, and nothing more than a Command window to execute them. You can also double-click files named with a .vbs extension or schedule them with Windows Task Scheduler. So, you already get a lot of mileage out of learning this one programming technique. But now, you can also select WSH Scripts from the Windows Script EX column in Designer 3, and InfoChannel and WSH will share variables.

What this means is that InfoChannel has gained the ability to communicate with and control Microsoft's popular tools for data interaction such as the Active Data Object (ADO) for databases, Collaborative Data Object (CDO) for emails, File System Object for files and MSXML Object for XML files. How this extends InfoChannel's capabilities, and the ways in which this can be used by the VAR to design new solutions around InfoChannel and pursue new opportunities is simply staggering.


Jun 28, 2004: Learning which version of WSH Engine you have

The first thing to do is to ensure that the latest version of the Windows Script Host is on your machine. As of the time of this writing, that is version 5.6.

The download pages are here...
http://msdn.microsoft.com/library/default.asp?url=/downloads/list/webdev.asp

As of the time of this writing, this is Microsoft's page for introducing and discussing the Windows Script Host...

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/script56/html/w...

To make sure you have the latest version, open a Command window and type the word cscript. It should tell you the version...



If you have a version later than 5.6 (or whatever is the latest at the time of this writing), find where Microsoft is giving out the latest version, and download and install it. It is always the best practice to backup your system before installing new software.


Jun 28, 2004: The 2 different Windows Script Engines

Now, in looking at this Command window, you can see that there are 2 different "script hosts" which can be selected from as the default. We just typed in cscript, which is one of them. But there is also wscript. The one you use depends on whether you want the script to execute as a command-line script or as a Windows program. This mostly means that when user input is required or output displayed, will it go to a command-line console or to a pop-up window. Think of the "c" in cscript as standing for Command, and the "w" in wscript as standing for Window.



If you were to write the Hello World program in VBScript and execute it from the cscript script host, it would look like this...



If you were to write the Hello World program in VBScript and execute it from the wscript script host, it would look like this...



Jun 28, 2004: Setting CScript As Your Default WSH Engine

For most of my uses, and for most of the uses appropriate for integration with InfoChannel, we will want to make cscript the default host. To do that, simply type into the command window...

cscript //H:CScript


It should look like this...



So now, when you want to test-run a script from the Command window, you only have to type the name of the script. You don't even need to include the path or the extension if the location of the script is your current directory. It makes it very easy for testing.


Jun 28, 2004: Hello World in VBScript for WSH

The next step is to write a Hello World program. It couldn't be easier. Make a new text file. Name it helloworld.vbs. And use a text editor such as Notepad to put the following line into the file...



WScript.Echo("Hello World!")


If you use notepad, it might look like this...



It's as easy as that. If you double-click this file, a Command console will pop up and disappear, maybe too fast for you to read. Once your default script host has been set to cscript, the best way to run a script that has no waiting for user input is to type it into the Command window. That way, you can see the output...



Jun 28, 2004: Choosing the first WSH example script

The main difference between writing in VBScript for WSH and VBScript for ASP is that WSH scripts don't use the pointy-percent brackets (<% %>) and the object you use for input and output is different. On the Web, developers have gotten used to the Response object. But the Response object is IIS/Web-specific. Under WSH, the equivalent object is the Wscript object. So, Response.Write under ASP becomes WScript.Echo under WSH.

Unfortunately, this means that scripts are not compatible between WSH and ASP. But they are easy to convert. Both ASP and WSH can use the valuable objects made available from Microsoft, such as ADO, CDO and the file system object. This means that most of the examples you find on the Web for VBScript under Active Server Pages are easily adaptable to VBScript under the Windows Script Host.

In deciding what my introductory script will be, I want to choose something that doesn't require much infrastructure. So, I'm ruling out the Active Data Object (ADO). Even just setting up data access with Microsoft Access is too much for a first example. Similarly, I'm ruling out the Collaborative Data Object (CDO), which is used for sending and receiving emails. That leaves the File System Object for reading files, and perhaps the Microsoft XML object (MSXML) for reading pages from the Web. Probably, reading pages from the Web is cooler (and better prepares us for data apps), but we will be able to control the conditions better if we just read and write a file from our own system. This will also make us look at file permission issues early on, which is good because it is one of the snafus that will be encountered later. The user account under which you are executing WSH scripts must have the required permissions to do whatever you ask it to do. Otherwise, you will get an error.


Jun 28, 2004: Pointers on programming defensively

“In order to be easy-to-use, VBScript was designed to be fault tolerant and to not require in-depth knowledge of object-oriented programming. This means that it is easy to let bugs accidentally enter your code.”In order to be easy-to-use, VBScript was designed to be fault tolerant and to not require in-depth knowledge of object-oriented programming. This means that it is easy to let bugs accidentally enter your code. So, effective scripting is all about proactively preventing bugs and memory leaks. Any object that you open should also be closed and set to "Nothing". Microsoft is pretty good about automatically cleaning up after bad scripts, but you should make the garbage collection task as easy as possible by programming defensively. Here are some pitfalls with programming in VBScript for WSH that you should be aware of...

VBScript is case-insensitive; meaning a variable named MyValue is the same as myValue. This means that you might think you have created a new variable, but what you're doing is actually overwriting an existing variable. You should make every variable name unique, and choose a consistent system for when you use upper and lower case.

VBScript by default does not require variables to be initialized, declared or dimensioned before being referred to. This leads to bugs where you evaluate against a misspelled variable name, encounter a problem, and never know you misspelled the name. To prevent this, the first line of every script should be "Option Explicit", which means that every variable must be "Dim'd" before being used...

Option Explicit
Dim myMessage
myMessage = "Hello World!"
WScript.Echo(myMessage)


All VBScript variables are of the variant datatype. That means they become the datatype you need as you refer to them. So, if you have a variable containing the value "1", it might be interpreted as the alphanumeric String "1", or as the integer "1" or as "True", based on how you use it in an evaluation. This eliminates the overhead of dealing with datatypes, but also creates some ambiguities.

VBScript is slightly object oriented. So, certain elements that you refer to in your script that seem to be variables are actually objects. You can generally tell the difference, because Objects require the "Set" keyword to come into existence, whereas normal variables don't.


Jun 28, 2004: Creating and Destroying an Object using the Set keyword

We already did our first baby-step script. It was the Hello World app. It doesn't get much easier than that. The fact to point out about it is that the Wscript object was used, without needing to be Dimensioned and Set. This is because it is automatically present because execution is being done by the Windows Script Host. Not all objects are that way. The file system object, for example, would need to be explicitly created.

With variables, the variable only needs to be Dimensioned. No cleanup is required when you're done with a variable...

Option Explicit
Dim myMessage
myMessage = "Hello World!"
WScript.Echo(myMessage)


But with objects (that are not built-into WSH), you need to use the "Set" keyword to create (or instantiate) the object. After you're done using the object, it is best to explicitly create a new object with the same name, set to "Nothing". Nothing is a special VBScript keyword that will free up any memory being used by an object of that name. Here, we create and destroy an incidence of the File System Object...

Option Explicit
Dim FSO
Set FSO = CreateObject("Scripting.FileSystemObject")
Set FSO = Nothing


This script will run, but absolutely nothing is being done here with the File System Object. That comes next.


Jun 28, 2004: Create the text file

A typical requirement for custom programming is to read and do something with the contents of a text file. Now, InfoChannel does already have the Text EX, which is dedicated to this purpose. InfoChannel also has native facilities to create custom log files. So, most reasons to resort to WSH for custom text file reading and righting is already rendered unnecessary due to InfoChannel's native power. But because I think the File System Object is the best to learn on, we will say for the sake of argument that we must read the contents of a text file.

When reading and dealing with the contents of a text file, you run into the concept of "parsing". What part of the file are you interested in? This in itself is a large topic, leading into the art of Regular Expression Matching (RegEx). But because we're keeping this tutorial simple, we are going to simply read a text file one line at a time.

First, we need a text file to read. To keep everything simple, we are going to work out of the same directory as the script. The account you are logged in as already has read permissions to this directory, or you would not have been able to run the Hello World script. So, create a new file on your hard drive with the following lines...

This is line one.
This is line two.
This is line three.
This is line four.
This is line five.
This is line six.


In notepad, it might look like this...



Jun 28, 2004: Checking for the existence of the file

Now that the text file exists, we can make our introductory program that loads the file system object actually do something. I've changed the name of the helloworld.vbs file to readfile.vbs. I then put the following program code in the file and saved. You should be able to copy-and-paste the code from here, but it is a good exercise to re-type the code. I'm going in such small steps, there is not a lot of typing.

Option Explicit
Dim FSO
Set FSO = CreateObject("Scripting.FileSystemObject")
If FSO.FileExists("textfile.txt") = True Then
     Wscript.Echo("File Found")
Else
     Wscript.Echo("File Not Found")
End If

Set FSO = Nothing


When you go to a Command window, and type readfile, you should see something like this...



Checking for the existence of the file before we attempt to do anything with it is an example of defensive programming. This if statements also introduces the first case of conditional branching.

I am not using full pathnames because everything is being found in the same directory, and that is the directory that my Command window has set to the current directory. This makes everything easy for a tutorial, and during development work. But as your projects get more sophisticated, it will be best to use full path names to your files, or variables that can be set to explicit paths.

You will also note how I highlight changes from one page to the next. Because my changes are sometimes so small, I point it out in a very strong way between pages.


Jun 28, 2004: Using OpenTextFile to open the text file

We only opened the File System Object and used it to check for the existence of the file. We still have yet to open the text file itself once found. This is how we do that. Notice how the incidence of the text file is also an object, and we symmetrically create and destroy it right away. Again, this is an example of defensive programming. When you use the OpenTextFile method of FSO, you make a TextStream object.

The OpenTextFile method of FSO has several parameters: the file name, the I/O mode, and whether the file can be created if it does not exist. Here, we open the file "For Reading Only", and tell it that it cannot create the file if it does not exist.

Option Explicit
Dim FSO
Set FSO = CreateObject("Scripting.FileSystemObject")
If FSO.FileExists("textfile.txt") = True Then
     Wscript.Echo("File Found")
     Dim MyTextStream
     Set MyTextStream = FSO.OpenTextFile("textfile.txt", 1, False)
     MyTextStream.Close
     Set MyTextStream = Nothing

Else
     Wscript.Echo("File Not Found")
End If
Set FSO = Nothing


The output of the program will look exactly the same as before. This step just opens and closes the text file without doing anything with it.

A word about how I am using capitalization: if the "Set" keyword was used to create an object, I use an initial capital letter. If it's just a variable, I use an initial lower-case letter. This lets me know at a glance whether I'm looking at a variable or an object. The reason I use "My" is because the name I'm chosing for the TextStream object is TextStream. MyTextStream implies that I am looking at a single instance of the TextStream object.

Some (especially C programmers) use extremely strict variable and object naming conventions. One such system is called Hungarian Notation. This becomes important when you're writing very large programs. But for scripting, it's usually good enough to name the variable with some meaningful name that will jog your memory later on about what it is used for.


Jun 28, 2004: Using the ReadAll method of the TextStream object

We now have the choice of reading the entire contents of the text file at once, or reading it line-by-line. Which you choose depends on what you're trying to accomplish. If you wanted the entire contents of the page loaded into a single variable, you would use the ReadAll method of the TextStream property. With this example, you can see how you can just dump the entire contents of the text file to the output window...

Option Explicit
Dim FSO
Set FSO = CreateObject("Scripting.FileSystemObject")
If FSO.FileExists("textfile.txt") = True Then
     Wscript.Echo("File Found")
     Dim MyTextStream
     Set MyTextStream = FSO.OpenTextFile("textfile.txt", 1, False)
     WScript.Echo(MyTextStream.ReadAll)
     MyTextStream.Close
     Set MyTextStream = Nothing
Else
     Wscript.Echo("File Not Found")
End If
Set FSO = Nothing


...which shows this...



This is the first time we really have shown anything based on the contents of the text file. So, this is something of a breakthrough. With this little bit of code, you have actually written a program that reads a text file and displays its contents.


Jun 28, 2004: Using the ReadLn method of the TextStream object

Using the ReadAll method of the TextStream object assumes that you need all the data in the text file at once. This would be appropriate to populate a single variable with the contents of the entire text file. But in many cases, you need to process the contents of a text file one line at a time. This is particularly true if you are pulling data from a log file where you know each line contains a single record. The output will look identical to the previous output, but it is getting there by a different means...

Option Explicit
Dim FSO
Set FSO = CreateObject("Scripting.FileSystemObject")
If FSO.FileExists("textfile.txt") = True Then
     WScript.Echo("File Found")
     Dim MyTextStream
     Set MyTextStream = FSO.OpenTextFile("textfile.txt", 1, False)
     'WScript.Echo(MyTextStream.ReadAll)
     Do While Not MyTextStream.AtEndOfStream = True
          WScript.Echo(MyTextStream.ReadLine)
     Loop

     MyTextStream.Close
     Set MyTextStream = Nothing
Else
     Wscript.Echo("File Not Found")
End If
Set FSO = Nothing


Here is the output...



To demonstrate how this is actually looking at a single line at a time, consider the following modification...

Option Explicit
Dim FSO
Set FSO = CreateObject("Scripting.FileSystemObject")
If FSO.FileExists("textfile.txt") = True Then
     WScript.Echo("File Found")
     Dim MyTextStream
     Set MyTextStream = FSO.OpenTextFile("textfile.txt", 1, False)
     'WScript.Echo(MyTextStream.ReadAll)
     Dim i: i = 1
     Do While Not MyTextStream.AtEndOfStream = True
          WScript.Echo("Line " & i & ": " & MyTextStream.ReadLine)
          i = i + 1
     Loop
     MyTextStream.Close
     Set MyTextStream = Nothing
Else
     Wscript.Echo("File Not Found")
End If
Set FSO = Nothing


...and output...



What we've done was to take advantage of the fact that we can do processing on each line in order to label the lines. A few other new concepts are introduced here...

A Do While Loop Not does a thing until the condition evaluates true. In this case, the condition evaluates true when the end of the file is reached. An error is not generated because the Do While Not logic prevents the flow from going into the loop once it has reached the end of file. Do While loops have something of a preemptive nature. They evaluate a condition before the condition can cause an error. Very useful.

We are also creating a simple integer counter. I set the counter equal to 1 at the start, because I know it will be used as a label, and I won't be incrementing the value until after it's gone through the first loop. I increment the counter with the old fashioned i = i + 1 statement instead of the modern shortcut i++ present in C++ (see a connection?) and Visual Basic 7, because VBScript doesn't support the ++ operator.

I use the concatenation operator, ampersand (&) to construct the line label. The important thing to notice here is that I'm concatenating something that had just had a math operator applied to it (so, it must clearly be a numeric data type) to a string literal. Yet, no errors are generated, and the label comes out correct. This is an example of the variant datatype in action. A variable datatype becomes what you need it to be based upon what you ask it to do.

I've also introduced the VBScript commenting character, the single-tick-mark ('). This character will turn the rest of whatever line it's on into a comment. This is similar to how the REM keyword worked in old BASIC. It's not as useful as the C and VBScript way of making comments, where you can easily block off entire blocks of comments with /* and */. Instead, you have to put the single tick mark at the beginning of every line. Single-tick-mark WILL NOT turn on commenting in the middle of a string literal. In other words, if you set a variable equal to "It's ok", it will be set correctly.

And finally, I set i equal to 1 on the same line as I use to Dim the variable. This shows how the colon (:) lets you put multiple VBScript commands on the same line. For consistency, I don't do this very often. But many languages let you declare a variable and set its initial value in the same step. For example, JavaScript would let you use var i = 1;, but because that's not available in VBScript, but I still like to put it on the same line, I use the colon.

Having so many subtle points in one small step is a great example of why I like to build things up in baby steps. Imagine how much knowledge a writer assumes when they build a tutorial with several steps mixed into one. Worse yet is when the writer creates some clever double-entendre designed to entertain those who already understand the concepts, but are completely confusing to those who are struggling through it for the first time.


Additional Information
Request DVD - Concepts and demo
Contact Scala Sales
Search