7

有没有办法读取MSI文件中的属性?

例如,给定一个名为Testpackage.msi的 MSI 文件,我需要找到

productName
PackageCode
version

我将在 WMI 卸载中使用它

string objPath = string.Format("Win32_Product.IdentifyingNumber='{0}', Name='{1}', Version='{2}'", "{AC9C1263-2BA8-4863-BE18-01232375CE42}", "testproduct", "10.0.0.0");

如果可以通过编程方式实现,使用Orca是一个不错的选择。然后我可以使用它来生成自动发行说明。并且在卸载程序中也是如此。

4

5 回答 5

7

您可以使用基于 COM 的 API 来处理 MSI,并执行类似的操作

Function GetVersion(ByVal msiName)

    Const msiOpenDatabaseModeReadOnly = 0
    Dim msi, db, view

    Set msi = CreateObject("WindowsInstaller.Installer")
    Set db = msi.OpenDataBase(msiName, msiOpenDatabaseModeReadOnly)
    Set view = db.OpenView("SELECT `Value` FROM `Property` WHERE `Property` = 'ProductVersion'")
    Call view.Execute()

    GetVersion = view.Fetch().StringData(1)

End Function
于 2008-11-30T10:32:20.213 回答
7

WiX 工具集 WiX 快速入门技巧(资源链接的集合)。WiX 安装 DTF。


我只想提一下,现在事情变得更加容易了。Windows Installer 对象模型有一个完整的 .NET 包装器,因此您可以避免任何 COM 互操作的笨拙

DTF - 入门:主文件:Microsoft.Deployment.WindowsInstaller.dll

  1. 下载并安装 WiX 工具包
  2. WixInstallPath\SDK在目录中找到以下文件

包装器称为“部署工具基础”(DTF),基本描述如下:“部署工具基础是一组丰富的 .NET 类库和相关资源,它们将 Windows 部署平台技术带入 .NET 世界。它旨在大大简化与部署相关的开发任务,同时仍然公开底层技术的完整功能”。

这是一个精简的动手示例

using (var db = new Database(FullPath, DatabaseOpenMode.ReadOnly))
{    
  PackageCode = db.SummaryInfo.RevisionNumber;
  AppVendor = db.SummaryInfo.Author;
  AppName = db.SummaryInfo.Title;
  ProductName = db.SummaryInfo.Subject;
  ProductCode = (string)db.ExecuteScalar("SELECT `Value` FROM "+
                 "`Property` WHERE `Property` = 'ProductCode'");
  AppVersion = (string)db.ExecuteScalar("SELECT `Value` FROM "+
                 "`Property` WHERE `Property` = 'ProductVersion'");
  UpgradeCode = (string)db.ExecuteScalar("SELECT `Value` FROM "+
                 " `Property` WHERE `Property` = 'UpgradeCode'");
}

主要 DTF 文件(后两个是最常用的):

  • Microsoft.Deployment.Compression.dll - 用于归档打包和解包的框架。
  • Microsoft.Deployment.Compression.Cab.dll - 实现文件柜归档打包和解包。
  • Microsoft.Deployment.Resources.dll - 用于在可执行文件中读取和写入资源数据的类。
  • Microsoft.Deployment.WindowsInstaller.dll - 完整的基于 .NET 的 Windows Installer API 类库。
  • Microsoft.Deployment.WindowsInstaller.Package.dll - 用于处理 Windows Installer 安装和补丁包的扩展类。

只需创建一个 C# 项目,引用这些文件,并使用您想要和需要的任何控件编写您自己的部署应用程序。目前我还没有设置 DTF 工具,但请参阅此示例以大致了解 C# 程序如何工作。

  • DTF 包含在 WIX 中。从这里下载 WiX
  • DTF dll 位于主 WiX 安装文件夹的 SDK 文件夹中(默认位置为:%ProgramFiles(x86)%\WiX Toolset v3.10\SDK)。当您看到此内容时,版本号可能会有所不同。只需在 %ProgramFiles(x86)% 下查找 WiX 文件夹。
  • 在“doc”文件夹中查找DTF 帮助文件。DTF.chmDTFAPI.chm。对象模型及其用法的绝对优秀文档。
  • 有关更多 DTF 详细信息,请参阅此 serverfault.com 帖子
  • 使用 WiX 的一些入门建议
于 2009-06-30T03:40:31.530 回答
6

您可以使用Microsoft 的 Orca.exe。Orca 将允许您打开 MSI 并编辑/查看其中的所有表格。您必须下载整个Windows SDK才能获得它,但幸运的是它是免费的。

一种替代方法(由于 SDK 的下载大小可能会更快)是使用来自WiX 项目的 dark.exe 。Dark 是一个 MSI 反编译器,它将所有内容导出到 XML 文件和资源集合中。它输出的 XML 将包含您要查找的信息。

于 2008-11-18T14:23:14.713 回答
3

这是 VBScript 中的一个类似示例,我将其用作创建引导程序可执行文件的构建过程的一部分...

Option Explicit
Const MY_MSI = "product.msi"

Dim installer, database, view, result, sumInfo, sPackageCode

Set installer = CreateObject("WindowsInstaller.Installer")
Set database = installer.OpenDatabase (MY_MSI, 0)

Set sumInfo = installer.SummaryInformation(MY_MSI, 0)
sPackageCode =  sumInfo.Property(9) ' PID_REVNUMBER = 9, contains the package code.

WScript.Echo "ProductVersion=" & getproperty("ProductVersion")
WScript.Echo "ProductCode=" & getproperty("ProductCode") 
WScript.Echo "PackageCode=" & sPackageCode 
WScript.Echo "ProductName=" & getproperty("ProductName") 

Function getproperty(property)

    Set view = database.OpenView ("SELECT Value FROM Property WHERE Property='" & property & "'")
    view.Execute
    Set result = view.Fetch
    getproperty = result.StringData(1)

End Function 
于 2009-06-30T13:00:39.237 回答
0

我在lessmsi中找到了一个轻量级的非编程解决方案。它显然使用 wix 并将整个 .msi 分解到指定的文件夹中。(它也有一个用户界面,但它在 Win7 上对我来说不是很好)。

于 2011-02-02T22:33:28.050 回答