簡體   English   中英

如何以編程方式讀取 MSI 文件中的屬性?

[英]How to programmatically read the properties inside an MSI file?

有沒有辦法讀取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 是一個很好的選擇,如果這可以通過編程實現,那么我可以使用它來生成自動發行說明。 並在卸載程序中。

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 - 用於 Windows Installer API 的完整的基於 .NET 的類庫。
  • 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 的一些入門建議

您可以使用基於 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

你可以使用微軟的 Orca.exe Orca 將允許您打開 MSI 並編輯/查看其中的所有表。 您必須下載整個Windows SDK才能獲得它,但幸運的是它是免費的。

一種替代方法(由於 SDK 的下載大小可能會更快)是使用WiX 項目中的dark.exe。 Dark 是一個 MSI 反編譯器,它將所有內容導出為 XML 文件和資源集合。 它輸出的 XML 將包含您正在尋找的信息。

這是 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 上對我來說效果不佳)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM