Windows Installer(MSI)をSQLでたたく

コードがVBScriptなのは、MSDNのサンプルがほとんどそうだったから。

既存のMSIにカスタムアクションを追加する程度ならそんなに難しくないはずでしたが、実はかなり面倒でした。この技法が有効なのは、Visual Studio Installerで作成したインストーラに簡単なシリアルチェックのカスタムアクションを追加する場合など(詳しくは、KB253683: How To Validate a Serial Number During an Installation Created with VSI)。

ここのコードも基本的には、このKBの記事を踏襲した上での処理だが、簡略化している。

Option Explicit

Const msiOpenDatabaseModeTransact = 1

' MSIファイルを書き込みモードで開く
Dim installer
Set installer = Wscript.CreateObject("WindowsInstaller.Installer")
Dim database
Set database = installer.OpenDatabase("hogehoge.msi", msiOpenDatabaseModeTransact)

' BinaryテーブルにDLLファイルをBlobとしてinsertする
Dim record
Set record = installer.CreateRecord(1)
record.SetStream 1, "c:\somewhere\\myCustomAction.dll"
database.OpenView("INSERT INTO Binary (Name,Data) VALUES (MyCustomActionDll', ?)").Execute record

' さっきのDLLを使って、カスタムアクションを定義
database.OpenView("INSERT INTO CustomAction (Action,Type,Source,Target) VALUES ('HogeCustomAction','1','MyCustomActionDll','DllFuncName')").Execute

' CustomTextAというダイアログでNextButtonが押されたときに、HogeCustomActionを実行する
' 注意: テーブルのキー要素はupdateできないので、一度deleteしてから、同じものをinsertする
database.OpenView("DELETE FROM ControlEvent WHERE Dialog_='CustomTextA' AND Control_='NextButton' AND Event='ValidateProductID'").Execute
database.OpenView("INSERT INTO ControlEvent (Dialog_,Control_,Event,Argument,Condition,Ordering) VALUES('CustomTextA','NextButton','DoAction','HogeCustomAction','','')").Execute

' 最後にコミットする
database.commit