【问题标题】:How can I modify an MSI in memory?如何修改内存中的 MSI?
【发布时间】:2012-05-03 20:37:28
【问题描述】:

我想将 MSI 文件读入 MemoryStream(或类似的东西),并对其进行修改。在不破坏 MSI 的情况下,最简单的方法是什么?

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

更新:

这是我的工作代码,使用 Windows 平台 SDK、对 Microsoft Windows Installer 对象库和命名空间 WindowsInstaller 的 COM 引用:

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();

【问题讨论】:

  • 您何时打算进行此更改有点不清楚。如果是在分发 MSI 之前,修改它可能没问题。如果它在之后(或者如果它是您从其他地方收到的 MSI),最好创建一个转换(或者如果属性是公共的,也许只需在命令行上修改它)。

标签: .net windows-installer memorystream


【解决方案1】:

查看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

【讨论】:

  • 我以前见过,它可以做我想做的事。问题是,我似乎无法弄清楚我需要向我的项目添加哪些参考资料。我已经安装了 Windows SDK(我现在正在下载示例),但我没有在它的目录中看到任何让我跳出来的东西。
  • 我想我找到了。有一个名为 Microsoft Windows Installer Object Library 的 COM 引用,它作为 WindowsInstaller 命名空间,其中包含安装程序和数据库对象。另外,这是我在 C# 中使用的指南:bit.ly/942ZZe。当我得到它的工作时,我会报告。谢谢你的好建议!
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2013-10-28
    • 1970-01-01
    • 1970-01-01
    • 2014-07-20
    • 2011-03-19
    • 1970-01-01
    • 1970-01-01
    • 2016-11-05
    相关资源
    最近更新 更多