Как программно прочитать свойства в файле MSI? - PullRequest
5 голосов
/ 18 ноября 2008

Есть ли способ прочитать свойства внутри файла 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 ]

6 голосов
/ 30 ноября 2008

Вы можете использовать API на основе COM для работы с 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
6 голосов
/ 30 июня 2009

Я просто хочу отметить, что теперь все стало еще проще. Существует полная оболочка .NET для объектной модели установщика Windows, так что вы можете избежать любых проблем взаимодействия COM * .

Оболочка называется " Deployment Tools Foundation " (DTF), и вот основное описание: " Deployment Tools Foundation - это богатый набор библиотек классов .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 для API установщика Windows.
  • Microsoft.Deployment.WindowsInstaller.Package.dll - Расширенные классы для работы с установщиком Windows и пакетами исправлений.

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

  • DTF включен в WIX. Загрузите WiX здесь .
  • Файлы 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: что лучше для непрерывной доставки?
6 голосов
/ 18 ноября 2008

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

Одной из альтернатив (которая может быть быстрее из-за размера загружаемого SDK) является использование dark.exe из проекта WiX . Dark - это декомпилятор MSI, который будет экспортировать все в файл XML и набор ресурсов. Выводимый им XML будет содержать информацию, которую вы ищете.

3 голосов
/ 30 июня 2009

Вот аналогичный пример в 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 
1 голос
/ 03 февраля 2011

Я нашел легкое непрограммное решение в lessmsi . Он, очевидно, использует wix и просто взрывает весь MSI-файл в указанную папку. (У него также есть пользовательский интерфейс, но он не очень хорош для меня на Win7).

...