Using JScript as a batch scripting language (Part III)
Article
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: