VBSCRIPT Subroutines in BATCH files |
This section demonstrates how the ":SetChar" routine in the "Special Characters (tabs etc)" section can be created from VBSCRIPT code.
If you are calling some VBSCRIPT from a batch file its possible that simply executing it is enough and you don't want anything returned however it is probably wise to return at least an errorlevel on failure, however environment variables might be easier (and required if you want to pass back anything else).
You are normally passing some information to the VBSCRIPT. If you wanted to return some information then you'd want the execution of the VBSCRIPT to create a temporary batch file which you can subsequently execute to set the environment up. For example the VBSCRIPT might create:
@echo off set ANSWER=The correct value set RC=5
The "Vbs4Cmd.VBS" program (see below) takes a well tested VBSCRIPT and creates a BATCH FILE fragment which can be imbedded in your batch file so it becomes standalone. As it is making some assumptions you may need to tweak the generated output.
Vbs4Cmd.VBS |
The code is written to create, execute & destroy the VBS each time its required. If its being invoked a lot of time you'd want to tweak the code to separate the VBS generation from its execution and also its destruction.
Copy & paste this code into a file called "Vbs4Cmd.VBS" (run it without any parameters for syntax and a description of what it does):
'---------------------------------------------------------------------------- ' MODULE NAME: Vbs4Cmd.VBS ' ' $Author: USER "Dennis" $ ' $Revision: 1.2 $ ' $Date: 13 Feb 2012 17:48:38 $ ' $Logfile: C:/DBAREIS/Projects.PVCS/Win32/MakeMsi/Vbs4Cmd.vbs.pvcs $ '---------------------------------------------------------------------------- '--- Init ------------------------------------------------------------------- const PgmVersion = "12.044" const ForReading = 1 const Indent = " " const ENABLEDELAYEDEXPANSION = true dim ErrTxt : ErrTxt = "" if ucase(mid(wscript.FullName, len(wscript.Path) + 2, 1)) = "W" Then GenerateErrorMsgText "You can't use WSCRIPT on this VB script, use CSCRIPT instead!" wscript.echo ErrTxt wscript.quit 999 end if set oFS = CreateObject("Scripting.FileSystemObject") if wscript.arguments.count = 0 then DisplayHelpAndQuit "Need at least one parameter (name of VBS)" else '--- Have at least one argument ----------------------------------------- if wscript.arguments.count > 2 then DisplayHelpAndQuit "Too many arguments (takes ONE or TWO)!" end if Vbs2ConvertFile = wscript.arguments(0) 'Want to generate this VBS via BATCH file (want standalone batch file with no pre-reqs) NumberOfParms = 0 'How many parameters does the VBS you are converting take? if wscript.arguments.count = 2 then NumberOfParms = wscript.arguments(1) if NumberOfParms > 9 then DisplayHelpAndQuit "The # of parameters to the VBSCRIPT must be from 0-9, make smaller value, fudge it and edit output if required!" end if end if end if if not oFS.FileExists(Vbs2ConvertFile) then DisplayHelpAndQuit "Could not find the VBS file """ & Vbs2ConvertFile & """" end if '--- Work out the name of the batch subroutine we are creating (from filename) --- NameOfSubroutine = oFS.GetBaseName(Vbs2ConvertFile) '--- How many parameters to pass? ------------------------------------------- if NumberOfParms <= 0 then VbsParms = "" else '--- Assume the subroutine will take and pass this many parameters ------- for x = 1 to NumberOfParms if x > 1 then VbsParms = VbsParms & " " VbsParms = VbsParms & """%~" & x & """" next VbsParms = " " & VbsParms end if '--- Mainline of Batch Subroutine ------------------------------------------- GenerateBatchFileLine "@rem ++++++++++++++++++++++++++++++++++++++" GenerateBatchFileLine ":" & NameOfSubroutine GenerateBatchFileLine "@rem ++++++++++++++++++++++++++++++++++++++ Generated from """ & Vbs2ConvertFile & """" GenerateBatchFileLine Indent & "set VbsFile=%TEMP%\" & NameOfSubroutine & "-%random%.vbs" GenerateBatchFileLine Indent & "set CmdFile=%TEMP%\" & NameOfSubroutine & "-%random%.cmd" GenerateBatchFileLine "" GenerateBatchFileLine Indent & "call :MAKEIT_" & NameOfSubroutine GenerateBatchFileLine "" GenerateBatchFileLine Indent & "cscript.exe //NoLogo ""%VbsFile%""" & VbsParms & " > ""%CmdFile%""" GenerateBatchFileLine Indent & "call ""%CmdFile%""" GenerateBatchFileLine "" GenerateBatchFileLine Indent & "del ""%VbsFile%"" >nul 2>&1" GenerateBatchFileLine Indent & "del ""%CmdFile%"" >nul 2>&1" GenerateBatchFileLine Indent & "goto :EOF" GenerateBatchFileLine "" '--- Generate the VBSCRIPT -------------------------------------------------- GenerateBatchFileLine "@rem ++++++++++++++++++++++++++++++++++++++" GenerateBatchFileLine ":MAKEIT_" & NameOfSubroutine GenerateBatchFileLine "@rem ++++++++++++++++++++++++++++++++++++++" set ReadStream = oFS.OpenTextFile(Vbs2ConvertFile, ForReading) LineCnt = 0 do while ReadStream.AtEndOfStream <> true GenerateVbScript rtrim(ReadStream.ReadLine) 'Keep leading whitespace for readability & want to be able to "round trip" the code loop ReadStream.close GenerateBatchFileLine Indent & "goto :EOF" set oFS = Nothing wscript.quit 0 '============================================================================ sub GenerateVbScript(ByVal VbScript) '============================================================================ '--- Need to escape some specific characters (for .CMD) ----------------- VbScript = replace(VbScript, "^", "^^") 'Need to double check this works, logic says its required... VbScript = replace(VbScript, "|", "^|") VbScript = replace(VbScript, "&", "^&") VbScript = replace(VbScript, ">", "^>") VbScript = replace(VbScript, "<", "^<") VbScript = replace(VbScript, "%", "%%") if ENABLEDELAYEDEXPANSION then VbScript = replace(VbScript, "!", "!!") end if '--- Output this line --------------------------------------------------- if VbScript = "" then VbScript = "." 'Want echo. else VbScript = " " & VbScript end if LineCnt = LineCnt + 1 if LineCnt = 1 then Redirection = " > " else Redirection = " >> " end if GenerateBatchFileLine Indent & "echo" & VbScript & Redirection & """%VbsFile%""" end sub '============================================================================ sub GenerateBatchFileLine(ByVal CmdBatchLine) '============================================================================ wscript.echo CmdBatchLine end sub '============================================================================ sub STDERR(ByVal HelpText) '============================================================================ ErrTxt = ErrTxt & HelpText & vbCRLF end sub '============================================================================ sub GenerateErrorMsgText(OptErrorMsg) '============================================================================ ErrTxt = "" STDERR "[]--------------------------------------------------------------------[]" STDERR "| VBS4CMD.VBS Version "& PgmVersion & " : Generates BATCH FILE CODE FROM VBSCRIPT |" STDERR "| (C)opyright Dennis Bareis 2012. All rights reserved |" STDERR "[]--------------------------------------------------------------------[]" STDERR "" STDERR "This tool converts some VBSCRIPT which may have been purpose written to be" STDERR "used in a batch file and converts this into a batch file subroutine which" STDERR "can create and execute the code." STDERR "" STDERR "This allows you to develop & test the VBSCRIPT outside of the batch file and" STDERR "only after its after fully tested do the reasonably painful conversion mostly" STDERR "automatically." STDERR "" STDERR "The main reason you'd want to do this is is to generate a self contained batch" STDERR "file rather than have with separate prerequisites." STDERR "" STDERR "The code is generated to SYSOUT for YOUR redirection and assumes the VBSCRIPT" STDERR "will return a result so it executes the VBSCRIPT then the expected generated" STDERR "BATCH FILE CODE b efore deleting all files, just delete or tweak as required :-)" STDERR "" STDERR "The VBSCRIPT if it returns results will return these as batch ""SET"" commands." STDERR "Please see the MAKEMSI manual for more information." STDERR "" STDERR "CORRECT SYNTAX" STDERR "~~~~~~~~~~~~~~" STDERR "cscript.exe //NoLogo VBS4CMD.VBS NameOfVbsFile [NumbParmsVbsTakes] [> OutFile]" STDERR "" STDERR "DETAILS" STDERR "~~~~~~~" '--- Display Error message ---------------------------------------------- if OptErrorMsg <> "" then STDERR "" STDERR "ERROR" STDERR "~~~~~" STDERR OptErrorMsg end if end sub '============================================================================ sub DisplayHelpAndQuit(OptErrorMsg) '============================================================================ '--- Display help ------------------------------------------------------- GenerateErrorMsgText(OptErrorMsg) wscript.stderr.writeline ErrTxt GenerateBatchFileLine "@rem ERROR:" & OptErrorMsg wscript.quit 777 end sub