ScriptControl用WScriptオブジェクト
2008年7月13日
Oyagameを、Registration-Freeで使うのにScriptControlを利用するやり方は、Oyagameに限定したツールにするよりも、汎用ツールとしてすべてのCOMに対応できるようにしたほうがよさそう。
先の記事でも問題にしたが、WScriptオブジェクトをこのツールで供給すれば、かなり汎用性が出るはず。しかも、XP, Vistaだけでなく、2000, NTでも使える方法を見つけてあるので、ほとんどのケースで問題ないだろう(95/98/MEでも使えるかどうかは、不明)。
このWScriptオブジェクトの供給方法について、ほぼ出来上がったので、バックアップの意味も兼ねてメモ。
EXEでScriptControlオブジェクトを作成し、上記コードをAddCode()する。つづけて、Run("suppon",IDispatch*,wchar_t*,wchar_t*)で、WScriptオブジェクトを得ることができるはず。ここでIDispatch*は、
・CreateObject()
・Quit()
・Sleep()
の3つのメソッドを持つオブジェクトへのポインタで、ここのCreateObject()が、Registration-Free COMに相当することになる。
最後に、実行するスクリプト用のScriptControlオブジェクトを作成し、上記のWScriptオブジェクトをこのScriptControlに持たせた後に、メインスクリプトを実行して終了。
ちなみに、上記コードはJScriptで書いてあるが、VBScriptでは書けない。クラスのメソッドにCreateObjectを記述すると、パースエラーを起こすため。
先の記事でも問題にしたが、WScriptオブジェクトをこのツールで供給すれば、かなり汎用性が出るはず。しかも、XP, Vistaだけでなく、2000, NTでも使える方法を見つけてあるので、ほとんどのケースで問題ないだろう(95/98/MEでも使えるかどうかは、不明)。
このWScriptオブジェクトの供給方法について、ほぼ出来上がったので、バックアップの意味も兼ねてメモ。
var WScript=new Object(); // Construct ScriptControl object WScript.ScriptControl=new ActiveXObject("ScriptControl"); WScript.ScriptControl.Language="VBScript"; WScript.ScriptControl.AddCode('sub suppon_msgbox(arg) msgbox arg,,"Windows Script Host" end sub'); // Method imprementations WScript.Echo=function(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10){ var args=new Array(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10); for(var i=0;i<10;i++) { if (args[i]!=null) this.ScriptControl.Run("suppon_msgbox",args[i]); } }; WScript.CreateObject=function(progID){ var obj; try{ obj=new ActiveXObject(progID); }catch(e){ obj=this.suppon_obj.CreateObject(progID); } return obj; }; WScript.Quit=function(i){ this.suppon_obj.Quit(i); }; WScript.Sleep=function(i){ this.suppon_obj.Sleep(i); }; // Initialize and return WScript object function suppon(obj,modulePath,cmdLine){ var fso = ActiveXObject("Scripting.FileSystemObject"); var i; WScript.suppon_obj=obj; WScript.FullName=modulePath; WScript.Name=fso.GetFileName(modulePath); WScript.Arguments=new Object(); WScript.Arguments.Length=0; WScript.Arguments.Item=new Array(); WScript.Arguments.Count=function(){ return this.Length; }; var temp=cmdLine+' '; if (temp.substr(0,1)=='"') { temp=temp.substr(1); i=temp.indexOf('"'); } else { i=temp.indexOf(' '); } if (i<0) i=temp.length; WScript.ScriptFullName=fso.GetAbsolutePathName(temp.substr(0,i)); WScript.ScriptName=fso.GetFileName(temp.substr(0,i)); temp=temp.substr(i+1); while(temp.length){ if (temp.substr(0,1)==' ') { temp=temp.substr(1); continue; } if (temp.substr(0,1)=='"') { temp=temp.substr(1); i=temp.indexOf('"'); } else { i=temp.indexOf(' '); } if (i<0) i=temp.length; WScript.Arguments.Item[WScript.Arguments.Length++]=temp.substr(0,i); } return WScript; }
EXEでScriptControlオブジェクトを作成し、上記コードをAddCode()する。つづけて、Run("suppon",IDispatch*,wchar_t*,wchar_t*)で、WScriptオブジェクトを得ることができるはず。ここでIDispatch*は、
・CreateObject()
・Quit()
・Sleep()
の3つのメソッドを持つオブジェクトへのポインタで、ここのCreateObject()が、Registration-Free COMに相当することになる。
最後に、実行するスクリプト用のScriptControlオブジェクトを作成し、上記のWScriptオブジェクトをこのScriptControlに持たせた後に、メインスクリプトを実行して終了。
ちなみに、上記コードはJScriptで書いてあるが、VBScriptでは書けない。クラスのメソッドにCreateObjectを記述すると、パースエラーを起こすため。