August 3, 2008

Windows Scripting Host and Javascript

Since every time I hear about Windows Scripting Host it is often associated with VB Scripting I decided to write this tutorial to help people (primarily novice programmers) who want to use JavaScript with Windows Scripting Host. This tutorial assumes you are fairly familiar with JavaScript. If you’re not, you’re probably in the wrong place. Hit google and start learning JavaScript

What is Windows Scripting Host

Windows Scripting Host is a standard feature on Windows operating systems since the days of Windows 98 and Internet Explorer 3.0. It is a piece of software which allows you to write scripts in several languages such as VB Script or JavaScript, and run them either interactively or in batch mode (eg. from the command line). Windows Scripting Host comes in two flavors cscript.exe and wscript.exe. cscript allows you to run a script from the command line, while wscript allows you run a script by doubleclicking on it. In this tutorial we will focus on the command line version ‘cscript’.

Getting Started

To get started, click on Start -> Run and type in cmd to open the command line. At the prompt type cscript and you should see something like the output below

Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

Usage: CScript scriptname.extension [option...] [arguments...]

Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

Usage: CScript scriptname.extension [option...] [arguments...]

Options:
//B         Batch mode: Suppresses script errors and prompts from displaying
//D         Enable Active Debugging
//E:engine  Use engine for executing script
//H:CScript Changes the default script host to CScript.exe
//H:WScript Changes the default script host to WScript.exe (default)
//I         Interactive mode (default, opposite of //B)
//Job:xxxx  Execute a WSF job
//Logo      Display logo (default)
//Nologo    Prevent logo display: No banner will be shown at execution time
//S         Save current command line options for this user
//T:nn      Time out in seconds:  Maximum time a script is permitted to run
//X         Execute script in debugger
//U         Use Unicode for redirected I/O from the console

If you got this far then Windows Scripting Host is working properly on your machine and we can get started with coding.

Setting up the environment

Create a new folder called idleworx_scripts (or whatever) in your root c:\ folder.

Hello World

Let’s write the simplest script possible using JavaScript and Windows Scripting Host.

1. Open notepad and enter the code below

<package id = "hello_world">
  <job id = "main">
    <script type="text/javascript">
          WScript.Echo("Hello World");
    </script>
  </job>
</package>

2. Save the file as hello_world.wsf in the folder you created about (eg. c:\idleworx_scripts\hello_world.wsf)

3. Open the windows command line and navigate to the folder c:\idleworx_scripts

4. Run the program by typing cscript hello_world.wsf

5. You should see Hello World printed on the command line.

Congrats, you just ran a very basic script using Windows Scripting Host
Notes
  1. Notice that to run a script using Windows Scripting Host you must put it in a *.wsf file. This allows the Windows Scripting Host to interpret it as an xml file and provide some useful parameters to your program as you’ll see later in this tutorial
  2. There is a way to call a *.js file directly as well [tutorial some other time]
  3. The and elements are required in the file. The <job> element allows you to separate your files into several programming modules.
  4. Inside the <job> element is where your actual program starts. Since we're writing script using JavaScript you have to specify the type of script you are using just like you would on a webpage.
  5. To print something to the console, you call the WScript.Echo(). ('WScript' is one of the 3 standard objects which Windows Scripting Host provides. The other being 'WshShell' and 'WshNetwork')

Hello World (with arguments)

Let's expand on the hello world example by using arguments. Arguments can be passed to your program from the command line by using a syntax similar to this:

cscript hello_world.wsf /name:Tom /age:25

By using Windows Scripting Host’s built in argument support you can make sure you users specify certain arguments as well as showing them how to properly call your script, as you will see shortly.

Let's make some changes to our original hello world program.

1. Open notepad and make the following changes to the hello_world.wsf file:

<package id = "hello_world">
<job id = "main">
  <runtime>
   <description>
   My hello_world.wsf program using Windows Scripting Host and JavaScript.
   </description>
   <named name="name" helpstring="Your name" type="string" required="true"/>
   <named name="age" helpstring="Your age" required="false" default="false" />
  </runtime>

<script type="text/javascript">
main();

function main(){

  var oArgs = WScript.Arguments.Named;

  if(oArgs!=null && oArgs.length>0)
  {
    WScript.Echo("Hi " + oArgs("name") + " you are " + oArgs("age") + " years old.");
  }
  else
  {
    WScript.Echo("You didn’t enter any arguments!");
    WScript.Arguments.ShowUsage();
    WScript.Quit();
  }
}
</script>

</job>
</package>

2. Now run the program with the command line:

cscript hello_world.wsf /name:John /age:25

3. You should see the output below:

Hi john you are 22 years old.

Notes
  1. First we have added a section to the program. This allows us to define parameters which can be passed from the command line to the program. We’ve defined a 'name' and an 'age' parameter, as well as provided a 'description' of what this program does.
  2. You’ll notice that we’ve changed the structure of the script part a bit. We created a main() method which will be the starting point of the script. This is setup is easier to work with.
  3. In order to read the arguments from the command line we loaded them in a variable called oArgsvar oArgs = WScript.Arguments.Named;
  4. In the following section we also check to see if the user hass passed in any argumentsif(oArgs!=null && oArgs.length>0) and if so display a welcome message using the arguments. Notice here that our code checks to see if any arguments have been passed in, it doesn’t validate for each one, so a user can just enter his age and his name will be left as ‘undefined’. You can now hopefully figure out how to add further validation to your arguments.

If the user hasn't passed in any arguments, we use the WScript.Arguments.ShowUsage() line to tell the user which arguments to pass in. This uses Windows Scripting Hosts' built in functionality for displaying the usage of a program (which we defined in the runtime section).

So if you call the program without any parameters:

cscript hello_world.wsf

You should see the following output:

You didn't enter any arguments!

My hello_world.wsf program using Windows Scripting Host and JavaScript.

Usage: hello_world.wsf /name:value [/age]

Options:

name : Your name
age  : Your age

Hopefully this all makese sense and you can see how easy it is to write basic programs with and without parameters.

Basic Template

To make things easier in the future copy the code below and use it as a template for any wsf file you want to run


<package id = "mypackage">
<job id = "myjob">
<runtime>
        <description>
              Description of your program.
        </description>
        <named name="argument1" helpstring="description of argument 1" type="string" required="true"/>
        <named name="argument2" helpstring="description of argument 2" required="false" default="false" />
</runtime>

<!-- If you have an external file you can easily included with the code below
    <script language="JavaScript" src="externalLibrary.js"/>
-->

<script type="text/javascript">
    main();
    function main(){
        var oArgs = WScript.Arguments.Named; //retreive arguments from command line
        if (oArgs != null && oArgs.length > 0) {
            //perform validation on arguments
            //you can check if an argument exists by using:  if(oArgs.Exists("dsn")) ...
            //WScript.Echo("argument1: " + oArgs("argument1"); //print an argument 

            //call other methods/functions in your program
            doSomething();
            doSomethingElse();
        }
        else {
            WScript.Echo("You didn't enter any arguments!");
            WScript.Arguments.ShowUsage();
            WScript.Quit();
        }
    }//end main()
    function doSomething(){
    }
    function doSomethingElse(){
    }
</script>
</job>
</package>

The End