如何以编程方式读取 MSI 文件内的属性?
-
08-07-2019 - |
题
有什么方法可以读取msi文件中的属性吗?
例如,给定一个 msi 文件名 Testpackage.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 是一个很好的选择,如果这可以通过编程实现,那么我可以使用它来生成自动发行说明。也在卸载程序中。
解决方案
您可以使用基于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
其他提示
您可以使用 Microsoft的Orca.exe 。 Orca将允许您打开MSI并编辑/查看其中的所有表。您必须下载整个 Windows SDK 为了得到它,但幸运的是,这是免费的。
另一种选择(由于SDK的下载大小可能会更快)是使用 WiX中的dark.exe项目。 Dark是一个MSI反编译器,它将所有内容导出到XML文件和资源集合中。它输出的XML将包含您要查找的信息。
我只想提一下,现在事情变得更加容易了。 Windows Installer 对象模型有一个完整的 .NET 包装器,因此您可以避免任何 COM 互操作的笨拙.
包装称为“部署工具基础“(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.压缩.dll - 归档打包和解包的框架。
- Microsoft.Deployment.压缩.Cab.dll - 实现柜档案打包和拆包。
- Microsoft.Deployment.Resources.dll - 用于在可执行文件中读取和写入资源数据的类。
- Microsoft.Deployment.WindowsInstaller.dll - 用于 Windows Installer API 的完整的基于 .NET 的类库。
- Microsoft.Deployment.WindowsInstaller.Package.dll - 用于使用 Windows Installer 安装和补丁包的扩展类。
只需创建一个 C# 项目,引用这些文件,并使用您想要和需要的任何控件编写您自己的部署应用程序。我目前尚未设置 DTF 工具,但请参阅 这个样本 了解 C# 程序如何工作的一般概念。
- DTF 包含在 WIX 中。 从这里下载 WiX.
- DTF dll 位于 WiX 主安装文件夹的 SDK 文件夹中(默认位置为:%ProgramFiles(x86)%\WiX 工具集 v3.10\SDK)。当您看到此内容时,版本号可能会有所不同。只需在 %ProgramFiles(x86)% 下查找 WiX 文件夹即可。
- 寻找 DTF 帮助文件 在“doc”文件夹中。 DTF.chm 和 DTFAPI.chm. 。关于对象模型及其用法的绝对优秀的文档。
- 看 这个 serverfault.com 帖子 有关更多 DTF 详细信息
- 使用 WiX 的一些入门建议: MSI 与 nuget 包:哪些更适合持续交付?
这是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
我在 lessmsi 中找到了一个轻量级的非程序化解决方案。它显然使用wix,只是将整个.msi爆炸到指定的文件夹中。 (它也有一个用户界面,但在Win7上对我来说并不好看。)