Still, I've been wanting to get something working in JScript.NET ...
A while back I wrote a tool in JScript to coordinate the Convert and Repair of Access databases. It works fine, albeit a little slowly being interpreted. It's short and, as it turned out, converted fairly easily once I began to get my head around the shift from Windows Scripting Host (WSH) to .NET.
In the original, I connected to the Scripting.FileSystemObject, using ActiveXObject(). I still do that in the JScript.NET version, simply because I haven't found out what the .NET equivalents are yet.
var oFSO = new ActiveXObject("Scripting.FileSystemObject");Next came parsing the command line. This is very easy in JScript and VBScript thanks to the WScript object's Arguments object, which even parses the command line into a dictionary, so that /name:<thing> is accessible as WScript.Arguments.Named("name") (as below):
var sDatabaseName = WScript.Arguments.Named("name"); var sDataFolder = WScript.Arguments.Named("data"); var sTempFolder = WScript.Arguments.Named("temp"); var sBackupFolder = WScript.Arguments.Named("backup");However, .NET's System.Environment.GetCommandLineArgs() is nowhere near as helpful, so I had to write something to parse the commandline that would at least come fairly close to the original in functionality.
function argNamed( sname : String ) { var result : String = ""; var aCmdline = System.Environment.GetCommandLineArgs(); var i : short = 1; for ( ; i < aCmdline.length; i++ ) { if (aCmdline[i].toLowerCase().slice(0, sname.length + 2) == ( "/" + sname.toLowerCase() + ":" )) { var inner : String = aCmdline[i].slice( sname.length + 2 ) result = (inner.charAt(0) == '"' ? inner.slice(1,inner.length-1) : inner); } } return result; } var sDatabaseName : String = argNamed("name"); var sDataFolder : String = argNamed("data"); var sTempFolder : String = argNamed("temp"); var sBackupFolder : String = argNamed("backup");Note that I'm using type annotations in the code to give the compiler a few hints about how to handle the intent of the code. Next, the handling the command line itself. Not a particularly good way of doing it in the original, but hey, it worked.
var bWorking = true; if ( undefined === sDatabaseName ) { WScript.Echo( "Specify database name with /name:With WScript.Quit() unavailable, I had to find something that would work in JScript.NET. I tried return and break but the compiler complained. Finally, I stumbled over System.Environment.Exit();." ); bWorking = false; } if ( undefined === sDataFolder ) { WScript.Echo( "Specify data path with /data: " ); bWorking = false; } if ( undefined === sTempFolder ) { WScript.Echo( "Specify temp folder with /temp: " ); bWorking = false; } if ( undefined === sBackupFolder ) { WScript.Echo( "Specify backup folder with /backup: " ); bWorking = false; } if ( ! bWorking ) { WScript.Quit(); }
if ( sDatabaseName == "" ) { print( "Please specify database name on commandline with /name:(Having a more sensible help text is next on the agenda.) Next I create the filenames that will be used later in the Access Compact and Repair process. These also appear in the JScript.NET version for the usual reasons (that is, I don't know yet how to do a BuildPath equivalent in .NET.)" ); System.Environment.Exit(1); } if ( sDataFolder == "" ) { print( "Please specify data path on commandline with /data: " ); System.Environment.Exit(2); } if ( sTempFolder == "" ) { print( "Please specify temp folder on commandline with /temp: " ); System.Environment.Exit(3); } if ( sBackupFolder == "" ) { print( "Please specify backup folder on commandline with /backup: " ); System.Environment.Exit(4); }
var sDatabaseFile = oFSO.BuildPath(sDataFolder, sDatabaseName); var sBackupFile = oFSO.BuildPath(sBackupFolder, sDatabaseName); var sTempFile = oFSO.BuildPath(sTempFolder, sDatabaseName);Next, assorted deletes, moves and the setup and execution of the CompactRepair Access.Application's CompactRepair() method.
try { oFSO.DeleteFile( sTempFile ); } catch ( e ) { //~ WScript.Echo( e.message + ': ' + sTempFile ); } WScript.Echo("CompactRepair",sDatabaseFile,"to",sTempFile); var oACC = new ActiveXObject('Access.Application'); oACC.CompactRepair( sDatabaseFile, sTempFile, true ); oACC.Quit(); try { oFSO.DeleteFile( sBackupFile ); } catch( e ) { //~ WScript.Echo( e.message + ': ' + sBackupFile ); } WScript.Echo("Moving",sDatabaseFile,"to",sBackupFile); oFSO.MoveFile( sDatabaseFile, sBackupFile ); // copy temp to source, overwriting try { oFSO.DeleteFile( sDatabaseFile ); } catch( e ) { //~ WScript.Echo( e.message + ': ' + sDatabaseFile ); } WScript.Echo("Moving",sTempFile,"to",sDatabaseFile); oFSO.MoveFile( sTempFile, sDatabaseFile ); WScript.Quit();The JScript.NET version is almost exactly the same:
try { oFSO.DeleteFile( sTempFile ); } catch ( e ) { //~ print( e.message + ': ' + sTempFile ); } print("CompactRepair ",sDatabaseFile," to ",sTempFile); var oACC = new ActiveXObject("Access.Application"); oACC.CompactRepair( sDatabaseFile, sTempFile, true ); oACC.Quit(); // copy source to backup, overwriting try { oFSO.DeleteFile( sBackupFile ); } catch( e ) { //~ print( e.message + ': ' + sBackupFile ); } print("Moving ",sDatabaseFile," to ",sBackupFile); oFSO.MoveFile( sDatabaseFile, sBackupFile ); // copy temp to source, overwriting try { oFSO.DeleteFile( sDatabaseFile ); } catch( e ) { //~ print( e.message + ': ' + sDatabaseFile ); } print("Moving ",sTempFile," to ",sDatabaseFile); oFSO.MoveFile( sTempFile, sDatabaseFile ); System.Environment.Exit(4);Notice the change from WScript.Quit() to System.Environment.Exit(). Notice also the change from WScript.Echo() to print(). One weird thing about the latter is that the arguments in a WScript.Echo() are output separated by a space, but are not separated at all in a print(), thus the extra spaces in the quoted strings. Sample invocation:
acarNET.exe /name:database.mdb /data:c:\acartest\data /temp:c:\temp /backup:c:\acartest\backupCompiled, the JScript.NET version runs very quickly in comparison to the original JScript version. It almost makes me wish JScript.NET had a future. As it stands, I'm going to have to redo this in something else. Sigh. © Copyright Bruce M. Axtens, 2012
1 comment:
Excellent information about jscript.
Post a Comment