残骸(だけど残しておく)

WindowsだろうとLinuxだろうと構わず動かしたいなーと思って最初はjavaにするかと思ったけどjreってそこまで確実にどのマシンにも入ってるわけではないと思ったので却下。それと小物ツールはソースが見えていてほしいなーと思うのでjavaはいまいち。ソース同梱すればいいかというと、実際に動いてるのとソースは実は違うとかなるのも面倒だし、そうなるとjavaだとjdkは必ずしも入ってる確率が高くないので却下。そこでふと(このブログは移転しました)を見つけた。
EmEditorは使わないけどDocument.*を消せば汎用的に使えたので使った。だけどVBSのIf(flag=0)'代入じゃなくて比較とかcaseのbreakがいらない?とかがきもいのでJScriptJScript.netで書き直した。正直ずるいやり方をしてみた。ところでJScript.netの色付けはシンタックス・ハイライトではなにを選べばいいんだろう?

//GetRuntimeDirectory.js
// jsc.exe /out:"GetRuntimeDirectory.exe" /t:exe "GetRuntimeDirectory.js"
import System;
System.Console.WriteLine(System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory());
// 参考: http://blogs.wankuma.com/mutaguchi/archive/2007/11/08/106978.aspx
var Fs = new ActiveXObject("Scripting.FileSystemObject");
var WshShell = new ActiveXObject("WScript.Shell");
var sCompilerDir = "C:/windows/Microsoft.NET/Framework/v2.0.50727/"
var getDotnetDirCommand = "./GetRuntimeDirectory.exe"

if (Fs.FileExists(getDotnetDirCommand)) {
  sCompilerDir = WshShell.Exec(getDotnetDirCommand).StdOut.ReadAll().replace(/\r\n/g, "");
  //WScript.Echo(sCompilerDir)
}

var sDefaultArguments = "/t:exe"; // or winexe
var sSourcePath = WScript.Arguments(0);
var sEXEPath = Fs.BuildPath(Fs.GetParentFolderName(sSourcePath), Fs.GetBaseName(sSourcePath) + ".exe");
var sExt = Fs.GetExtensionName(sSourcePath).toLowerCase();

//var sCompilerPath = sCompilerDir + sExt + "c.exe"; // kimeuti
var sCompilerPath = ""; 
switch (sExt) {
  case "vb" : sCompilerPath = sCompilerDir + "vbc.exe"; break;
  case "cs" : sCompilerPath = sCompilerDir + "csc.exe"; break;
  case "js" : sCompilerPath = sCompilerDir + "jsc.exe"; break;
}
	
if (sCompilerPath == "") {
  WScript.Echo( sExt + "ファイルに対応するコンパイラがありません。");
} else {
  // Beep: http://d.hatena.ne.jp/miya2000/20080815/p0
  WScript.Echo(String.fromCharCode(7));
  sCommandLine = "cmd.exe /k " + sCompilerPath + " " + "/out:" + "\"" + 
  sEXEPath + "\"" + " " + sDefaultArguments + " " + "\"" +
  sSourcePath + "\"" + " && " + sEXEPath + " & " + "pause && exit";
  WshShell.Run(sCommandLine, 1, true); //コンパイル&実行
  /*
  if (Fs.FileExists(sEXEPath)) WshShell.Run(sEXEPath, 5, true); //コンパイルしたファイルを実行
  else WScript.Echo( "コンパイルに失敗したようです。");
  */
}

ほんとならJScriptで完結させられるとベストなんだけど、jscript.net使ってjsc.exeとかがあるディレクトリを取って、それを実行ファイルにしてjscript側から呼んでる。もちろん事前にパスをファイルに書き込んでしまえば、こんなコマンドいらないけど。

これのファイル名は適当にdotnet1liner.jsとか付けてJScript.netのソースをhoge.jsだとするとcscript dotnet1liner.js hoge.jsとかすればコンパイルする。コンパイルが成功したら実行、失敗したらcscriptのエラーメッセージ眺めて適当なキー押して終了。