以前のエントリで、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になる。
セコメントをする