以前のエントリで、J(ava)?ScriptからVBScriptのコードを実行する方法を紹介したが、やはり
vb.Run( "VbFunc", param1, param2 )とかって、文字列ベースで呼び出すのはなんとなく落ち着かない。さらに、JavaScript使ってるのに引数の数が束縛されるのも個人的には落ち着かない。 なので、ラッパーを作ってみることにした。
prototype.jsと、String.format、さらにEnumeratorのEnumerable化が前提だが、こんな感じ。
// VBScript実行エンジンラッパークラス
var VBScript = Class.create();
VBScript.prototype = {
initialize : function() {
this._vbe = new ActiveXObject("ScriptControl");
this._vbe.Language = "VBScript";
},
addFunction : function(code) {
this._vbe.AddCode( code );
this._copyMembers();
},
reset : function() {
this._vbe.reset();
[ "initialize", "addFunction", "reset", "_copyMembers" ].each( function(key) {
delete( this[ key ] );
} );
},
_copyMembers : function() {
var self = this;
var vbe = this._vbe;
new Enumerator( vbe.Procedures ).each( function(proc) {
self[ proc.Name ] = function() {
var args = arguments;
var p = $R( 0, proc.NumArgs, true ).map( function(i) {
return args[i];
} );
return eval( "vbe.Run( \"{0}\", {1} )".format(
proc.Name,
p.map( function(obj, i) { return "p[{0}]".format( i ); } ).join(", ")
) );
}.bind( self );
} );
}
}
ごめんなさい。クラス名がベタなのは勘弁してください。
var vb = new VBScript;
vb.addFunction( "Function prompt(msg, title) : prompt = InputBox(msg, title) : End Function" );この例では、Functionプロシージャを1つ登録しているだけだが、1回のaddFunction()で一気に複数のプロシージャを食わせることができる。まだ試していないが、.vbsファイルを読み込んで直接流し込むことができると思う。
// VBS関数名で直接呼び出せる vb.prompt( "なんか入力すれ。", "VBS テスト" );VBSの定義より引数が多い場合は自動的に切り詰められ、少ない場合はundefined(多分VBSではNothing扱い)が渡されるので、引数の数によるエラーは発生しない。 ちなみに、VBS側がSubプロシージャで登録されていた場合、実行結果は当然undefinedになる。
セコメントをする