How to programmatically read the properties inside an MSI file?

半腔热情 提交于 2019-11-26 16:56:27

问题


Is there any way to read the properties inside the msi file?

For example given a msi file name Testpackage.msi

I need to find

productName
PackageCode
version

This I am going to use it with WMI uninstall

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

Update: Using Orca is a great option, if this can be achieved programatically, then I can use this to generate automatic release notes. and in un-install program too.


回答1:


You can use the COM-based API for working with MSI, and do something like

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



回答2:


You can use Microsoft's Orca.exe. Orca will allow you to open the MSI and edit/view all the tables in it. You will have to download the entire Windows SDK in order to get it, but thankfully that is free.

One alternative (which might be faster due to the download size of the SDK) is to use dark.exe from the WiX project. Dark is a MSI decompiler, which will export everything into an XML file and collection of resources. The XML it outputs will have the information you are looking for.




回答3:


WiX toolset: WiX quick-start tips (collection of links to resources). WiX installs DTF.


I just want to mention that things have gotten even easier now. There is a full .NET wrapper for the Windows Installer object model, so you can avoid any COM interop clunkiness.

DTF - Getting Started: Main file: Microsoft.Deployment.WindowsInstaller.dll

  1. Download and install the WiX toolkit
  2. Find the files below in the WixInstallPath\SDK directory

The wrapper is called "Deployment Tools Foundation" (DTF) and here is the basic description: "Deployment Tools Foundation is a rich set of .NET class libraries and related resources that together bring the Windows deployment platform technologies into the .NET world. It is designed to greatly simplify deployment-related development tasks while still exposing the complete functionality of the underlying technology".

Here is a stripped-down, hands-on sample:

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'");
}

Primary DTF files (the latter two are the most used ones):

  • Microsoft.Deployment.Compression.dll - Framework for archive packing and unpacking.
  • Microsoft.Deployment.Compression.Cab.dll - Implements cabinet archive packing and unpacking.
  • Microsoft.Deployment.Resources.dll - Classes for reading and writing resource data in executable files.
  • Microsoft.Deployment.WindowsInstaller.dll - Complete .NET based class library for the Windows Installer APIs.
  • Microsoft.Deployment.WindowsInstaller.Package.dll - Extended classes for working with Windows Installer installation and patch packages.

Just create a C# project, reference these files, and code your own deployment application with whatever control you desire and need. I am not set up with the tools for DTF at the moment, but see this sample for a general idea of how a C# program would work.

  • DTF is included with WIX. Download WiX from here.
  • The DTF dlls are in the SDK folder in the main WiX installation folder (the default location is: %ProgramFiles(x86)%\WiX Toolset v3.10\SDK). The version number will probably be different by the time you see this. Just look for the WiX folder under %ProgramFiles(x86)%.
  • Look for the DTF help files in the "doc" folder. DTF.chm and DTFAPI.chm. Absolutely excellent documentation for the object model and its usage.
  • See this serverfault.com post for some more DTF details
  • Some starter suggestions for working with WiX: MSI vs nuget packages: which are is better for continuous delivery?



回答4:


Here's a similar example in VBScript which I use as part of my build process in creating bootstrapper executables...

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 



回答5:


I found a lightweight non-programmatic solution in lessmsi. It apparently uses wix and just explodes the whole .msi into a specified folder. (It also has a UI but it didn't render great for me on Win7).



来源:https://stackoverflow.com/questions/298841/how-to-programmatically-read-the-properties-inside-an-msi-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!