如何在内存中修改MSI?

时间:2010-03-03 17:49:59

标签: .net windows-installer memorystream

我想将一个MSI文件读入MemoryStream(或类似的东西),然后修改它。在不破坏MSI的情况下,最简单的方法是什么?

我需要做的就是修改MSI中某个属性的值。我更喜欢.Net中的某些东西,但我对其他平台开放。

更新

这是我的工作代码,使用Windows平台SDK,对Microsoft Windows Installer对象库的COM引用和命名空间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();

2 个答案:

答案 0 :(得分:3)

查看Windows SDK,使用Windows Installer API时包含大量示例。

这是我用来执行此操作的命令行VBScript的简化版本:

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

答案 1 :(得分:0)

尽管这篇文章真的很老,但是为了碰巧通过搜索引擎到达这里的用户,有一个非常简洁的.Net库,它实现了Windows Installer SDK的几乎所有功能,并且通过以下方式主动维护: Rob Mensching,微软高级开发人员。它存在于Wix工具集中,您可以获得v3.6 RC0 here. 安装此工具集后,添加对此工具集的安装目录中存在的Microsoft.Deployment.WindowsInstaller.dll的引用,您很高兴。 您可以轻松地将整个msi数据库加载到DataSet中并执行所需的读/写操作,最后将更改提交给msi。