If you want to write scripts for Windows, you have some unattractive options. You can use the DOS batch-file scripting language, but that’s a little on the primitive side. You can learn PowerShell (Monad), a typically overwrought, idiosyncratic MSFT affair. Or, you can pursue a better option: you can use JavaScript to script Windows.
The Environment
Windows Script Host (WSH) is a scripting environment available in Windows 98 and later MSFT OSes. A script can access this environment when it is executed by one of two special interpreters – cscript or wscript. (The cscript interpreter is a console application, while wscript is a GUI application.)
When these interpreters execute a JavaScript file (they can also execute vbScript, and WSH can be extended to support other languages – but the less said about that, the better) they place certain objects into the script’s global namespace. It is these objects that allow the JavaScript code to interact with the operating system outside of the interpreter. The two most interesting objects are:
- WScript
- ActiveXObject
WScript provides the core environment; it makes arguments available, permits output to the console, and so on.
ActiveXObject is a constructor; when certain strings are passed to it, it will return ActiveX objects which perform useful functions. Some of the more interesting strings/ActiveX objects:
- WScript.Shell
- Scripting.FileSystemObject
- WScript.Network
WScript.Shell lets a script execute command-line utilities, FileSystemObject provides access to the local disk, and Network provides (very) basic features related to Windows networking. It should be noted that the objects returned by the ActiveXObject constructor don’t seem to be proper JavaScript objects; taking the typeof() their methods, for instance, yields a value of “unknown”. Caveat coder.
Documentation
The available documentation for WSH is bloody awful. Here are some resources I found; they’re not very good. Unfortunately, it seems to take a little detective work to figure out how to make WSH do what one wants. It’s still preferable to batch files or PowerShell.
Examples
Here are some simple examples of WSH scripts. To run one, just save it to disk as a *.js file (e.g. hello.js) and then invoke it with cscript like this:
- cscript hello.js
// The canonical simple example
WScript.Echo('Hello, World');
// Print the current user's domain and username
var o = new ActiveXObject('WScript.Network');
WScript.Echo(o.UserDomain + '\\' + o.UserName);
// Take a list of filenames from the command line, and print the number of lines
// in each file. Relative pathnames work, wildcards don't.
//
// To invoke: cscript wc.js foo.txt
// or: cscript wc.js foo.txt bar.js
// or: cscript wc.js foo.txt bar.js ..\baz.txt
//
// (Assuming you saved the code to a file named 'wc.js', of course.)
function CountLines(fso, pn)
{
try
{
var n = 0; fp = fso.OpenTextFile(pn, 1);
}
catch (e)
{
return 0;
}
while (!fp.AtEndOfStream) { n++; fp.ReadLine(); }
fp.Close();
return n;
}
var i, l, pad, pn, fso = new ActiveXObject("Scripting.FileSystemObject");
// I'm not proud of this formatting technique
for (i = 0, l = 0; i < WScript.Arguments.length; i++)
{
l = Math.max(l, WScript.Arguments(i).length);
}
pad = (new Array(l+3)).join(' ');
// Calculate and output the results
for (i = 0; i < WScript.Arguments.length; i++)
{
pn = WScript.Arguments(i);
WScript.Echo((pn+pad).slice(0,l+2) + CountLines(fso, pn));
}