views:

56

answers:

1

I'd like to read an MSI file into a MemoryStream (or something similar), and modify it. What's the easiest way to do this, without corrupting the MSI?

All I need to be able to do is modify the value of one of the properties in the MSI. I'd prefer something in .Net, but I'm open to other platforms.

Update:

Here's my working code, using the Windows platform SDK, a COM reference to Microsoft Windows Installer Object Library and namespace WindowsInstaller:

Installer installer = Activator.CreateInstance(Type.GetTypeFromProgID("WindowsInstaller.Installer")) as Installer;

Database msi = installer.OpenDatabase("WixTest.msi", MsiOpenDatabaseMode.msiOpenDatabaseModeTransact);

View view = msi.OpenView("update `Property` SET `Property`.`Value`='99' where `Property`='USERID'");

view.Execute(null);

msi.Commit();
+1  A: 

Check out the Windows SDK, there are a bunch of samples included on using the Windows Installer API.

Here's a simplified version of a command line VBScript I use to do this:

Option Explicit


Const msiOpenDatabaseModeReadOnly     = 0
Const msiOpenDatabaseModeTransact     = 1

Dim openMode : openMode = msiOpenDatabaseModeTransact

Dim argCount:argCount = Wscript.Arguments.Count

If (argCount < 3) Then  WScript.Echo "usage: msisetproperty.vbs <msi> <property> <value>" :     WScript.Quit 1

Dim MY_MSI : MY_MSI = Wscript.Arguments(0)
Dim sProp1 : sProp1 = Wscript.Arguments(1)
Dim sVal1  : sVal1 = Wscript.Arguments(2)

Dim filesys : Set filesys=CreateObject("Scripting.FileSystemObject")

If Not filesys.FileExists(MY_MSI) Then WScript.Echo "Unable to find msi, exiting" : WScript.Quit 1

Dim installer, database, view, result

Set installer = CreateObject("WindowsInstaller.Installer")
Dim sumInfo  : Set sumInfo = installer.SummaryInformation(MY_MSI, 0)

Set database = installer.OpenDatabase (MY_MSI, openMode)

Set view = database.OpenView ("UPDATE Property SET Value='" & sVal1 & "' WHERE Property='" & sProp1 & "'")
view.Execute

database.Commit
Set database = nothing
sascha
I've seen that before, and it does what I'd like to do. The problem is, I can't seem to figure out what references I need to add to my project. I have the Windows SDK installed (I'm donwloading the samples now), but I didn't see anything in its directory that jumped out at me.
Mike Pateras
I think I've found it. There's a COM reference called Microsoft Windows Installer Object Library, which as a WindowsInstaller namespace, which has the installer and database objects. Also, here's the guide I'm using to do it in C#: http://bit.ly/942ZZe. I'll report back when I get it working. Thanks for the great suggestion!
Mike Pateras
Got it working. Thanks again!
Mike Pateras
No problem, happy to help!
sascha