Here’s a small chunk of code from a recent request asking how to write to the Windows Installer binary stream using Powershell:
$msiOpenDatabaseModeReadOnly = 0
$msiOpenDatabaseModeTransact = 1
$windowsInstaller = New-Object -ComObject windowsInstaller.Installer
$pathToMSI = "C:\Users\xxxx\Desktop\AlkaneExample.msi"
$database2 = $windowsInstaller.GetType().InvokeMember("OpenDatabase", "InvokeMethod", $null, $windowsInstaller, @($pathToMSI, $msiOpenDatabaseModeTransact))
$query = "INSERT INTO `Binary` (`Name`,`Data`) Values(?,?)"
$View = $database2.GetType().InvokeMember("OpenView","InvokeMethod",$Null,$database2,($query))
$binaryrecord = $windowsInstaller.GetType().InvokeMember("CreateRecord", "InvokeMethod", $null, $windowsInstaller, 2)
$binaryrecord.GetType().InvokeMember("StringData", "SetProperty", $null, $binaryrecord, @(1, "AlkaneBinary"))
$fileToStream = "C:\Alkane\AlkaneFile.txt"
$binaryrecord.GetType().InvokeMember("SetStream","InvokeMethod", $null, $binaryrecord, @(2, $fileToStream))
$View.GetType().InvokeMember("Execute", "InvokeMethod", $Null, $View, $binaryrecord)
$database2.GetType().InvokeMember("Commit", "InvokeMethod", $null, $database2, $null)
$View.GetType().InvokeMember("Close", "InvokeMethod", $Null, $View, $Null)
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($View) | Out-Null
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($binaryrecord) | Out-Null
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($database2) | Out-Null
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($windowsInstaller) | Out-Null


Thanks Kae!!
It worked perfectly! Just a note for anyone else trying to add a custom action with binary data i.e. VB script, remember to match the name column “AlkaneBinary” in the binary table with the Source column in the custom action table.
Thanks again.
Jim
When i try to run the code below, it fails. What am i doing wrong?
$msiOpenDatabaseModeReadOnly = 0
$msiOpenDatabaseModeTransact = 1
$windowsInstaller = New-Object -ComObject windowsInstaller.Installer
$pathToMSI = “C:\Temp\Test.msi”
$database = $windowsInstaller.GetType().InvokeMember(“OpenDatabase”, “InvokeMethod”, $null, $windowsInstaller, @($pathToMSI, $msiOpenDatabaseModeTransact))
$query = “INSERT INTO `Binary` (`Name`,`Data`) Values(?,?)”
$View = $database.GetType().InvokeMember(“OpenView”, “InvokeMethod”, $Null, $database, ($query))
$binaryrecord = $windowsInstaller.GetType().InvokeMember(“CreateRecord”, “InvokeMethod”, $null, $windowsInstaller, 2)
$binaryrecord.GetType().InvokeMember(“StringData”, “SetProperty”, $null, $binaryrecord, @(1, “Test”))
$fileToStream = “C:\Temp\test.txt”
$binaryrecord.GetType().InvokeMember(“SetStream”, “InvokeMethod”, $null, $binaryrecord, @(2, $fileToStream))
$View.GetType().InvokeMember(“Execute”, “InvokeMethod”, $Null, $View, $binaryrecord)
$View.GetType().InvokeMember(“Close”, “InvokeMethod”, $Null, $View, $Null)
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($View) | Out-Null
….I’d need more information on the error.