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を記述すると、パースエラーを起こすため。