cscriptで起動しなおす2007年04月30日 02時06分14秒

WScript.exeっていまいち使わなくね?

特に設定をいじっていないと.jsや.vbsはWScript.exeをホストとして実行されるが、このままだとWScript.Echoがいちいちポップアップになるので、デバッグには不便になる。

ま、//HオプションでCScriptを既定にしておけばいいんだけど、だれかに配布したりしても大丈夫なように、WScriptで起動されていたらCScriptで起動しなおすようにすることもできるかと。定番なんだけどね。

基本的な考え方

基本的には、起動したスクリプトファイル自体を明示的にCscript.exeに渡してやればいいんだけど、以下の点をクリアする必要がある。

  1. WScript.exeで起動されている場合のみ起動しなおす(でないと、永遠に同じスクリプトをcscriptに渡しつづけるから)
  2. 起動時の引数を引き継ぐ必要がある

まず起動されたスクリプトなわけだが

まずは実行されたスクリプトファイル自体のパスがわからないと話にならないが、これは至極簡単。WScript.ScriptFullNameプロパティに現在のスクリプトのフルパスが格納されているのでそれを参照すればOK。

WScript?CScript?

次に、どちらのホストで起動されたかを判断するわけだが、これも簡単で、WScript.FullNameプロパティを確認する。WScript.FullNameプロパティは、起動時のWScriptホストのフルパスが格納されているので、

/wscript\.exe$/i.test( WScript.FullName )
とすると、WScriptで起動されていたらtrueがかえる。

引数を引き継ぐ

これはコマンドライン引数の展開みたいな面倒なことはしないで、WScript.Argumentsプロパティを全部列挙して半角スペースでjoinすれば問題なし。

コードサンプル

function createArgs() {
	var result = [];
	var args = new Enumerator( WScript.Arguments );
	for(; ! args.atEnd(); args.moveNext()) {
		result.push( args.item() );
	}
	return result;
}

var args = createArgs();

if( /wscript\.exe$/i.test( WScript.FullName ) ) {
	new ActiveXObject("WScript.Shell").Run(
		"cscript \"" + WScript.ScriptFullName + "\" " +
		args.join(" ")
	);
	// ここでこのスクリプトは終了しておく
	WScript.Quit();
}

// パラメータを列挙
for(var i = 0; i < args.length; i++) {
	WScript.Echo( i + ": " + args[i] );
}

// 入力待ち
WScript.StdIn.ReadLine();