A syntax error or a run-time error causes WSH to terminate script execution with the error message shown in Figure 2-13. The message includes the path and the filename of the script as well as the error category and an error description. It usually also shows the line number and the column in which the error occurred.
Figure 2-13 The error message that terminates a script's execution in WSH 2
You can also use one of the editors mentioned earlier in the chapter to identify the line that caused the error. After amending the source code, you can run the next test. If the script doesn't contain any more syntax errors, you can begin debugging.
For testing purposes, you can use the file ErrorTest.vbs in the \WSHDevGuide\Chapter02 folder. The VBScript program contains a syntax error that brings up the error message shown in Figure 2-13. To execute the script correctly, you must edit the source code so that the string constant in line 13 is closed with a double quote (").
After removing all syntax errors from a WSH script, you can start functional tests. In most cases—except in trivial script programs—the script probably won't deliver the expected result. Sometimes it's helpful to place statements in the source code to display a message box with interim results. Each time such a statement is executed, a message box is displayed. In the message box, you can show script interim values and messages. This approach is shown in Listing 2-1.
Listing 2-1 WSHDemo.vbs
'********************************************** ' File: WSHDemo.vbs (WSH sample in VBScript) ' Author: (c) G. Born ' ' Showing interim results in a message box '********************************************** ' The following lines deactivate and activate ' the trace messages. You must uncomment the ' appropriate line. ' DebugFlag = False ' Trace output off DebugFlag = True ' Trace output on j = 0 debug "Start:", 0, 0 For i = 1 To 10 ' Loop 10 times. debug "Step:", i, j j = j + i ' Add all numbers. Next debug "End:", i, j WScript.Echo "Result:", j Sub debug(text, count, val) If DebugFlag Then ' Debug mode active? WScript.Echo text, count, " Interim result:", val End If End Sub '*** End
The program in Listing 2-1 is very simple. It uses a loop to calculate the sum of the numbers from 1 to 10, and it displays the results using the Echo method. For testing purposes, however, it's helpful to know when the program enters the loop and how many steps are executed within the loop. To trace these steps, you can call the Echo method within the loop or at an appropriate place. To keep the code as simple as possible, all trace messages are evaluated in their own procedure with the name debug. Thus, the program needs only the following statement to show the values used in the loop:
debug "Step:", i, j
The first parameter defines the text shown in the message box. The other parameters can contain numbers, which are also shown in the message box. In Listing 2-1, the debug procedure is called in several places. Within the loop, the debug call shows the index value and the calculated interim value, as shown in Figure 2-14.
Figure 2-14 A message box with trace values
When you test the program, the trace values should appear as shown in Figure 2-14. Once the script runs flawlessly, these trace messages are no longer needed, so you can remove them from the source code. But if you change something later in the program, you'll need the trace statements again. Removing and replacing trace statements is unnecessary in the WSHDemo.vbs, however, because you can control the trace output using an option in the debug procedure. This procedure contains the following condition:
If DebugFlag Then ' Debug mode active?
Only if the value of the global variable DebugFlag is set to True is the Echo method called and the message box displayed. The variable DebugFlag is set in the script's header to the value True, as shown here:
' DebugFlag = False ' Trace output off DebugFlag = True ' Trace output on
At any given time, one of the statements is active and the other is commented out, so you can toggle the value of DebugFlag between True and False by moving the comment sign from one line to the other. The trace output is shown or suppressed based on the value of DebugFlag.
The script file WSHDemo.vbs (along with WSHDemo.js) is in the \WSHDevGuide\Chapter02 folder.
You can use the technique shown in the preceding section only for simple scripts. If a script causes run-time errors or unexpected results, you must use a debugger to trace the program and its values. The Microsoft Script Debugger, which you can download free from http://msdn.microsoft.com/scripting, tests scripts in HTML documents or Active Server Pages (ASP) files. You can also use the debugger to test WSH scripts.
When you download the Microsoft Script Debugger, it is installed in the \Program Files\Microsoft Script Debugger folder. The debugger comes in different versions for Windows 95, Windows 98, and Windows NT. Windows 2000 already includes the Microsoft Script Debugger. It's also possible to use the debugger that comes with Microsoft Script Editor, which ships with Microsoft Office 2000.
So how do you execute a script under the control of the debugger? WSH supports commands to launch the script debugger and execute the script under the control of the debugger. However, you need to know about some differences between WSH 1 and WSH 2, and you also can use a special command to debug .wsf files.
In WSH 1, you can insert the Stop statement in VBScript and the debugger statement in JScript; these statements invoke the debugger automatically when executed.
If you insert the Stop statement in VBScript files and the debugger statement in JScript files, as you do in WSH 1, nothing happens with the debugger in WSH 2.
To use the debugger in WSH 2, you must invoke the script using the //D switch. The following command forces WSH to enable script debugging:
WScript.exe //D C:\WSHDevGuide\Chapter02\ErrorTest2.vbs
After executing the first Stop statement (in VBScript) or debugger statement (in JScript), the debugger is launched and control is passed to the program, as shown in Figure 2-15. Then you can execute the script step by step in the debugger. (See also the section "Debugging Features" in Chapter 1.)
Figure 2-15 Enabling script debugging statements
If you don't want to insert Stop and debugger statements in your script code, you can use the //X flag to invoke the debugger, as shown here:
WScript.exe //X C:\WSHDevGuide\Chapter02\WSHDemo.vbs
WSH 2 launches the debugger and passes control to this program. The debugger stops script execution when it encounters the first executable command (as shown in Figure 2-16).
Figure 2-16 Executing scripts under debugger control
The sample files ErrorTest1.vbs and ErrorTest1.js in the \WSHDevGuide\Chapter02 folder contain a statement that shows a message box. The sample files ErrorTest2.js and ErrorTest2.vbs in the same folder contain the Stop and debugger statements.
One way to debug .wsf files is to add a <?job …?> processing instruction with the debug attribute set to true (as mentioned in Chapter 1). Listing 2-2 contains such an instruction.
Listing 2-2 ErrorTest.wsf
<?xml version="1.0"?> <!-- File: ErrorTest.wsf (for WSH 2.0) Author: (c) G. Born --> <job id="T1"> <?job debug="true"?> <script language="VBScript"> <![CDATA[ Stop WScript.Echo "Hello, VBScript" ]]> </script> <script language="JScript"> <![CDATA[ debugger WScript.Echo ("Hello, JScript"); ]]> </script> </job>
This file can be executed with or without the //X or //D option; a double-click on the .wsf file invokes the debugger automatically if a Stop or debugger statement is executed. The following processing instruction in the .wsf file disables debugging in WSH 2. (It is independent of the //X or //D setting in the script's command line.)
This statement comes in handy if you want to suppress debugging in .wsf files that contain Stop or debugger commands.
Once the Microsoft Script Debugger takes control of script execution, the source code appears in the debugger window (as shown earlier in Figure 2-15). You can step through the source code, but you can't edit it in the debugger window. To edit the source code, you must load it into a separate window.
The Microsoft Script Debugger contains several toolbars and menu commands for testing the script, as shown in Figure 2-17 and described in the following list. (Some commands can also be invoked using keystrokes.)
The Command Window button opens a window in which you can enter and execute program statements directly. The Call Stack button opens a window that shows the names of all active procedures on the stack. The stack is empty if your script uses only a linear program structure (one without calling procedures or functions).
Figure 2-17 Toolbar buttons in the debugger window
During debugging, Step Into (single-step) mode can be helpful. You click the Step Into button or press F8 to execute the next statement in a script. The next executable statement is marked on the left border of the debugger window with an arrow (as shown in Figure 2-17).
If your script contains already tested procedures and functions, single-step mode doesn't makes sense for executing the statements in these procedures or functions. Instead, you can use the Step Over button or press Shift+F8. If the next executable statement contains a procedure or function call, the entire procedure or function is executed without any disruption. Execution stops after control returns to the caller. If you use this command to execute other statements that don't call a procedure or function, it works like Step Into mode.
If the debugger hits a breakpoint within a procedure or a function, you can use the Step Out button or press Ctrl+Shift+F8 to finish executing all the statements in the procedure or function. The debugger then breaks at the first statement following the call to the procedure or function.
To interrupt script execution on a certain statement, you can use breakpoints. Select the statement in the debugger window and then set the breakpoint by using the Toggle Breakpoint button or by pressing F9. If you resume program execution, the debugger stops execution if the line with the breakpoint is reached.
You can use the Call Stack command on the View menu or the Call Stack button on the toolbar to open the Call Stack window (shown in Figure 2-18), which lists all active procedures and functions. In the figure, the Message procedure from Calls.vbs is being executed.
Figure 2-18 The Call Stack window
If a program is interrupted, you can inspect the current value of a variable (or a property) in the Command window. In VBScript, you type a question mark followed by a variable name (for example, ? color) to show the associated value (as shown in Figure 2-19).
Figure 2-19 Showing variable values in the Command window
In JScript, you must use a statement such as WScript.Echo(color); to show a variable value using the Command window. The debugger executes the statement and displays a message box with the value of the variable color.
To set the value of a variable, you enter the statement to associate a value with a variable into the command window, as shown here:
Message = "Hello, world"
The preceding techniques allow you to easily debug a WSH script written in VBScript or in JScript.