Using JScript as a batch scripting language (Part III)

Now that I’ve shown how to build a cool .Format() method for strings, we can put it to good use in a lot of places.

In batch scripting, it’s really nice to be able to make nearly every call support replacement arguments in a consistent fashion. In cmd.exe batch scripts, we use %var% all over the place. In JScript batch scripting, we simply use {$VAR} instead, and put a little bit of code in the top of our functions to help out with that.

First, the one-stop-universal-arguments helper, which we can add to the source from before:

Scripting.js
 function ArgsToArray(x) { return Array.prototype.slice.call(x);} // FormatArguments must be passed either://     one argument: //          containing the arguments object from the caller//          where the first argument of that should be the format string.//          == or ==//          just the format string.////     two arguments://          the first argument is the format string//          the second argument is the argument collection from the caller.function FormatArguments(args, moreargs) {    var result = "";    if (arguments.length == 1) {        if (typeof (args) == "object") {            args = ArgsToArray(args);            result = "" + (args.shift());            if (args.length == 1 && arguments[0].length > 0)                args = arguments[0];            return result.Format(args);        } else return ("" + args).Format();    } else if (arguments.length == 2) {        if (typeof (args) == "string" && typeof (moreargs) == "object") {            result = args;            args = ArgsToArray(moreargs);            args.shift();            return result.Format(args);        }    }    throw "Invalid Argument passed to FormatArguments";}

FormatArguments()   gives us the ability to do variable substitution in any function, in a very flexible way. You can simply use the function to give you a completed string:

Test-4.js
 // use the first string as the format string, // the rest are potential value substitutionsfunction Test1() {    var foo = FormatArguments(arguments)    WScript.echo( foo );}Test1("the path is {$PATH}");// both arguments are used as format strings. any // parameter substitution should use numbers starting// at {1}, since the 'destfile' parameter is techincally {0}function Test2(srcfile, destfile) {    var srcfile = FormatArguments(srcfile, arguments);    var destfile = FormatArguments(destfile, arguments);    var msg = "Copy {0} to {1}".Format(srcfile, destfile);    WScript.echo(msg);}Test2("{$WINDIR}\\system32\\notepad.exe" , "{$USERPROFILE}\\desktop\\notepad.exe");

Knowing that, we can create a few functions that will use the FormatArguments function:

Scripting.js
 // Some global objects we'll need var WSHShell = WScript.CreateObject("WScript.Shell");var WinShell = WScript.CreateObject("Shell.Application");var procEnvironment=WSHShell.Environment("PROCESS")var fso = new ActiveXObject("Scripting.FileSystemObject");function Print() {    WScript.echo(FormatArguments(arguments));}function cd() {    WSHShell.CurrentDirectory = FormatArguments(arguments);}function pwd() {    return WSHShell.CurrentDirectory;}function erase(file) {    file = FormatArguments(arguments);    if (exists(file))        fso.DeleteFile(file);}function rmdir(folder) {    folder = FormatArguments(arguments);    if (folderExists(folder))        fso.DeleteFolder(folder, true);}function exists(file) {    return fso.FileExists(FormatArguments(arguments));}function folderExists(folder) {    return fso.FolderExists(FormatArguments(arguments));}function mkdir(folder) {    folder = FormatArguments(arguments);    if (!folderExists(folder))        fso.CreateFolder(folder);}

Now, we can do some pretty nifty little batch scripting:

test-5.js
 // Bootstrap Scripting Libraryeval(new ActiveXObject("Scripting.FileSystemObject").OpenTextFile("Scripting.js", 1, false).ReadAll());$ORIG_DIR = pwd();if( exists("{$WINDIR}\\log.txt") ) {    Print("Deleting log file");    erase("{$WINDIR}\\log.txt");}mkdir("{$TEMP}\\tempdir");

Next time, we’ll see how we can call on command-line tools to do our bidding, and play with the results.