Visual Basic scripts can be executed 'Windows style' or from a command prompt. This depends on which interpreter executes the script. Wscript.exe does it Windows style (e.g. with message boxes and other GUI stuff) and is the default : Wscript will execute the script when you double click it. Sometimes it's more convenient to run a script from a command line, e.g. when a script needs command line arguments or uses stdin and stdout (standaard input and output), or when running scripts from a batch file. In that case, you will want Cscript.exe to execute your script.
To control how the script is executed, you can use something like the following piece of code :
If Ucase(Right((wscript.FullName),11)) <> "CSCRIPT.EXE" Then ' if not using cscript, show error msg CRLF = chr(13)&chr(10) wscript.echo ( "Engine = " & Right((wscript.FullName),11) & CRLF & CRLF &_ wscript.ScriptName & " must be executed with cscript" & CRLF & _ " eg. c:\cscript " & wscript.ScriptName & " [arguments] " ) Else 'execute script by calling subroutine main main End If wscript.quit '----------------------------------------------------------------------------------------------- 'main script here Private Sub Main Wscript.echo "OK" End Sub
Taking this one step further, in stead of giving an error message and quit, the script could be forced to run with cscript, even if the user (explicitly or not) called wscript. To accomplisch this, the script will first check whether or not cscript is used, and if not, it will open a shell and run itself with cscript. That would look something like this :
If Ucase(Right((wscript.FullName),11)) = "CSCRIPT.EXE" Then
main
Else
'run this script, using cscript
set oShell = createObject ("Wscript.Shell")
CommandLine = "cscript " & wscript.ScriptFullName
oShell.Run CommandLine
End If
wscript.quit
'-----------------------------------------------------------------------------------------------
'main script here
Private Sub Main
wscript.echo wscript.FullName & " -- OK"
Wscript.Sleep 10000
End Sub
note the 'Wscript.Sleep 10000' statement. This pauses the script for 10 seconds (10000 millisec) so you can actually see the output :-)
In the previous script, we needed to get properties of the script itself, such as its name, the interpreter that runs it, etc. Here's a number of interesting script properties - wrapped in a script so that you can see them in action :
TAB = chr(9) CRLF = chr(13) & chr(10) wscript.echo "wscript.Name :" & TAB & wscript.Name wscript.echo "wscript.ScriptName :" & TAB & wscript.ScriptName wscript.echo "wscript.ScriptFullName :" & TAB & wscript.ScriptFullName wscript.echo "Engine - from Fullname :" & TAB & Right((wscript.FullName),11) & CRLF & _ "or in short :" & TAB & Left(Right((wscript.FullName),11),7) wscript.echo "the script's directory :" & TAB & _ Left(Wscript.ScriptFullName, (Len(Wscript.ScriptFullName) - Len(Wscript.ScriptName)-1)) '__________________________________ 'for command line execution : allow user to read output wscript.Sleep 10000
If a script requires arguments, but none are provided, it will return an error and quit. Therefore, you need to check for arguments first, by counting them, like If WScript.Arguments.Count > 0 Then ..., or If WScript.Arguments.Count = 2 Then ....
If the .Count is OK, you can use the values. The simpliest way to get the values in to your script is like this :
If lcase(WScript.Arguments.Item(0)) = "default" Then (...) theVariable = lcase(WScript.Arguments.Item(5) (...)
This clearly assumes that the arguments are given in a certain order, else you won't know which argument is 'item 5'. That's OK for simple scripts / commands with a limited number of arguments, or where the order is relevant. Compare with the 'copy' command :
copy source destination
For more elaborate scripts with lots of arguments, and where not all arguments are required, you could use a function that checks all parameters, and saves the value of each in the appropriate variable that you can then use in the rest of the script. This allows you to create scripts that take parameters like so :
doSomething.vbs -s source -d destination -m 666 -v .
You can collect these into your script and use the given values somewhat like this :
'ArgHandler set Args = wscript.arguments For i = 0 to (Args.count -1) select case Args.item(i) case "-v": boolVerbose = True case "-s": strSourcePath = Args.item (i + 1) case "-d": strDestinationPath = Args.item (i + 1) case "-m": intModus = Cint(Args.item (i + 1)) end select Next 'show / use input : wscript.echo "the input was :" & chr(10) wscript.echo "v: " & boolVerbose wscript.echo "s: " & strSourcePath wscript.echo "d: " & strDestinationPath wscript.echo "m: " & intModus wscript.echo chr(10)
The obvious way to prompt for input in a script is to use an InputBox :
theValue = InputBox ("give a value : ", Wscript.ScriptName, "yes").
We can use this to prompt the user for input in case a required value is missing form the arguments list :
If WScript.Arguments.Count < 4 Then
'argument #5 is missing, ask for it :
theValue5 = InputBox ("where do you want to go today ?", Wscript.ScriptName)
Else
theValue5 = WScript.Arguments.Item(5)
End If
InputBox produces a GUI dialogue box - even when the script is running with cscript. To remain in text mode when prompting for input, vbs provides access to StdIn and StdOut (standard In/Output : keyboard and text on screen - or redirected with < ). This can be used like this :
Set ConsoleInput = WScript.StdIn Set ConsoleOutput = WScript.StdOut ConsoleOutput.WriteLine "enter path to destination file : " 'or use wscript.echo theInput = ConsoleInput.ReadLine 'can be put in a loop with ' Do While Not ConsoleInput.AtEndOfStream ' 'to handle input that consists of multiple lines, eg. when reading redirected or piped input 'show that input is saved in variable : wscript.echo "you have entered : " & theInput
To combine this with the Argument Handler routine, you wouldn't check the argument itself, but the variable that is supposed to get its value :
'initialise : make sure you start with an empty var strSourcePath = "" set Args = wscript.arguments For i = 0 to (Args.count -1) select case Args.item(i) case "-s": strSourcePath = Args.item (i + 1) end select Next 'if the variable is still empty, the -s argument was not given, ' so promt for input, and don't give up till you get it If strSourcePath = "" Then wscript.echo "the source path is required. Please enter the source path : " Set cin = WScript.StdIn Do While strSourcePath = "" strSourcePath = cin.ReadLine Loop End If 'prove wscript.echo strSourcePath
When you need to handle 'dirty' output, e.g. from StdOut (output of commands run at the command prompt), you often end up with strings that are full of tabs, newlines, carriage return, lots of spaces for formatting, etc. These characters bevome a pain in the lower part of the back when you want a clean string (an ip address from ipconfig, a FQDN from nslookup, ...). The trim() function only deals with spaces - on CR/LF or tab and you're out. The following function handles all whitespace / Line feed characters that may be surrounding the string you actually want :
Function cleanupString (theString) ' clean up a string from StdOut etc : remove spaces, tabs and newlines / carriage returns theString = Trim (theString) Do While ( ASC(Right(theString,1)) < 33 OR _ ASC(Right(theString,1)) > 127 ) theString = Left (TheString, Len(TheString)-1) Loop Do While ( ASC(Left(theString,1)) < 33 OR _ ASC(Left(theString,1)) > 127 ) theString = Right (TheString, Len(TheString)-1) theString= Trim (TheString) Loop cleanupString = theString End Function