Как программно прочитать свойства в файле MSI?

Есть ли способ прочитать свойства внутри 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 - отличный вариант, если это может быть достигнуто программно, то я могу использовать это для создания автоматических заметок о выпуске. и в деинсталляционной программе тоже.

5 ответов

Решение

Вы можете использовать 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

Я просто хочу отметить, что теперь все стало еще проще. Существует полная оболочка.NET для объектной модели установщика Windows, так что вы можете избежать любых проблем взаимодействия 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.Compression.dll - платформа для упаковки и распаковки архивов.
  • Microsoft.Deployment.Compression.Cab.dll - Осуществляет упаковку и распаковку архивов кабинета.
  • Microsoft.Deployment.Resources.dll - классы для чтения и записи данных ресурсов в исполняемые файлы.
  • Microsoft.Deployment.Windows Installer.dll - полная библиотека классов на основе.NET для API установщика Windows.
  • Microsoft.Deployment.Windows Installer.Package.dll - Расширенные классы для работы с установщиком Windows и пакетами исправлений.

Просто создайте проект C#, ссылайтесь на эти файлы и кодируйте свое собственное приложение развертывания с любым управлением, которое вы пожелаете и в чем нуждаетесь. В настоящий момент я не настроен на использование инструментов для DTF, но посмотрите на этот пример, чтобы получить общее представление о том, как будет работать программа на C#.

  • DTF включен в WIX. Загрузите WiX отсюда.
  • DLL-файлы DTF находятся в папке SDK в основной папке установки WiX (расположение по умолчанию: %ProgramFiles(x86)%\WiX Toolset v3.10\SDK). Номер версии, вероятно, будет отличаться к тому времени, когда вы увидите это. Просто найдите папку WiX в%ProgramFiles(x86)%.
  • Найдите файлы справки DTF в папке "doc". DTF.chm и DTFAPI.chm. Абсолютно отличная документация по объектной модели и ее использованию.
  • Посмотрите эту запись serverfault.com для некоторых подробностей DTF
  • Несколько начальных советов по работе с WiX: пакеты MSI против nuget: что лучше для непрерывной доставки?

Вы можете использовать Microsoft Orca.exe. Orca позволит вам открыть MSI и редактировать / просматривать все таблицы в нем. Вам нужно будет загрузить весь Windows SDK, чтобы получить его, но, к счастью, это бесплатно.

Одна альтернатива (которая может быть быстрее из-за размера загрузки SDK) - использовать dark.exe из проекта WiX. 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).

Другие вопросы по тегам