Получение версии файла MSI (построена с помощью WiX) - PullRequest
8 голосов
/ 03 мая 2009

Я создал файл MSI с WiX. Исходный файл WiX содержит информацию о версии, например:

<Product Id="..." 
         Name="..." 
         Language="1033" 
         Version="1.0.0.1" 
         Manufacturer="..." 
         UpgradeCode="...">

Файл MSI работает нормально: он устанавливается, удаляется, обновляется при увеличении номера версии и т. Д.

Однако, когда я пытаюсь получить информацию о версии этого файла, вызывая API MsiGetFileVersion (), он возвращает ошибку 1006 (ERROR_FILE_INVALID Файл не содержит информацию о версии.)

Отсюда мой вопрос: как (программно, в C ++) получить номер версии файла MSI? Или, другими словами, куда в файле WiX должна идти информация о версии, чтобы ее можно было извлечь через MsiGetFileVersion ()?

Дополнительная информация: та же ошибка возникает с MSI 3.0 в Windows XP и MSI 4.0 в Vista.

Ответы [ 3 ]

7 голосов
/ 03 мая 2009

Для справки, вот пример VBscript, который я использую в процессе сборки, чтобы захватить его перед созданием Boostrapper.

Dim installer, database, view, result

Set installer = CreateObject("WindowsInstaller.Installer")
Set database = installer.OpenDatabase ("my.msi", 0)

Dim sumInfo  : Set sumInfo = installer.SummaryInformation("my.msi", 0)
sPackageCode =  sumInfo.Property(9) ' PID_REVNUMBER = 9, contains the package code.

WScript.Echo getproperty("ProductVersion")
WScript.Echo getproperty("ProductVersion")
WScript.Echo sPackageCode
WScript.Echo 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 
6 голосов
/ 03 мая 2009

Для полноты картины :: MsiGetFileVersion () - это функция, которая считывает информацию о ресурсах версии из PE-файла (.exe или .dll) того же , что и установщик Windows. Это важно для использования инструментами сборки (такими как WiX ), чтобы они правильно заполняли информацию File / @ Version. Это не даст вам информацию о версии из MSI. Как показывает @sascha, вы можете запросить таблицу свойств для «ProductVersion» или использовать :: MsiGetProductProperty (), который сделает то же самое.

4 голосов
/ 03 мая 2009

Нашел решение: вместо вызова MsiGetFileVersion (), вызовите:

MSIHANDLE hProduct = NULL;
MsiOpenPackage( pszPath, &hProduct );

MsiGetProductProperty( hProduct, _T("ProductVersion"), pszVersion, &dwSizeVersion );

MsiCloseHandle( hProduct );

(обработка ошибок опущена)

...