プログラミング

registration-free COMをWSHで使う

2008年7月1日

OyagameやSFC-miniは、インプロセスCOMサーバ(ActiveX-DLL)をregsvr32.exeを使ってレジストリに登録するという古い方法を使って、WSH(VBScript/JScript)でDLLにアクセスすることを可能にしている。WSH自身がすでに古くなりつつある技術なので、こういった古い技術に頼るのは仕方の無いところ。

一方で、こういった資産を生かそうという仕組みがWindows XP以降ではサポートされているようで、これを使えば、レジストリへの登録無しに、COMサーバが使える。したがって、管理者権限が無くても、COMサーバが供給するオブジェクトにアクセスすることができるようになる。

Oyagameを使うようなケースではこれは朗報で、作成したプログラムを配布する時の制限が無くなる事は大きい。

で、どのようにすればOyagameでこれが可能になるのか調査したので、メモ。

まず、oyagameのuninstall.vbsを実行しておいて、アンインストールした状態にしておく。次に、作業用の適当なフォルダを作成。ここでは、manifestという名のフォルダとする。このmanifestフォルダに、以下のファイルをコピー。

・oyagame.dll
・SDL.dll
・wscript.exe (%SystemRoot%\system32からコピー)

manifestフォルダーに、wscript.exe.manifestという名で以下の内容を含むテキストファイルを作成。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity
    version="1.0.0.1"
    processorArchitecture="x86"
    name="sfcmini.wscript"
    type="win32"
/>

<description>WScript.exe</description>

<dependency>
    <dependentAssembly>
        <assemblyIdentity
            type="win32"
            name="sfcmini.oyagame.dll"
            version="1.0.0.1"
            processorArchitecture="x86"
        />
    </dependentAssembly>
</dependency>

</assembly>

manifestフォルダーに、sfcmini.oyagame.dll.manifestという名で以下の内容を含むテキストファイルを作成。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity
    version="1.0.0.1"
    processorArchitecture="x86"
    name="sfcmini.oyagame.dll"
    type="win32"
/>

<file name="oyagame.dll">
    <comClass description="oyagame Class"
        clsid="{B0716439-9915-4c1a-9D69-AD9A1DDC4C5C}"
        threadingModel="apartment"
        progid="sfcmini.oyagame"
        tlbid="{B0716439-9915-4c1a-9D69-AD9A1DDC4C5C}"
    />
</file>

</assembly>

これで、manifestフォルダーにコピーしたwscript.exeを介してvbsファイルもしくはjsファイルを実行すれば、レジストリに登録することなく(インストールすることなく)、oyagameを利用することができる。

もう少しすっきりした方法でoyagameを使えないかと色々調べているが、CreateProcessで新規プロセスを実行した場合は、親プロセスのCOMマッピングは継承されないようなので、この手は使えない。他には、ScriptControlオブジェクトを介する方法が使えそうだが、ScriptControlって、XP以降では必ずインストールされているものなのだろうか?それと、この場合にエンコードされたスクリプト(VBE, JSE)をどうやって実行するかが良く分からず、これも解決しないといけない問題だ。

コメント

Kat (2008年7月1日 19:58:13)

vbeを使う場合、.language="vbscript.encode"で良いらしい。サンプルスクリプト:

set sc=CreateObject("ScriptControl")
sc.language="vbscript.encode"
sc.addcode "#@~^JgAAAA==d!4~D+kY`D#@#@&:ko8WXPO@#@&+x9~/!4@#@&+QkAAA==^#~@ "
'sub test(t)
'msgbox t
'end sub
sc.run "test","OK"

Kat (2008年10月13日 14:36:21)

Supponを使えば、もっと簡単にできます。
http://www.rad51.net/nucleus/index.php?itemid=669

コメント送信