Получение версии файла MSI (построена с помощью WiX)
-
03-07-2019 - |
Вопрос
Я создал файл 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.
Решение
Для полноты картины :: MsiGetFileVersion () - это функция, которая считывает информацию о ресурсах версии из PE-файла (.exe или .dll) в то же , что и установщик Windows. Это важно для инструментов сборки (таких как набор инструментов WiX ) для правильного заполнения информацией File / @ Version , Это не даст вам информацию о версии из MSI. Как показывает @sascha, вы можете запросить таблицу свойств для " ProductVersion " или вы можете использовать :: MsiGetProductProperty (), который будет делать то же самое.
Другие советы
Для справки, вот пример 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
Нашел решение: вместо вызова MsiGetFileVersion () вызовите:
MSIHANDLE hProduct = NULL;
MsiOpenPackage( pszPath, &hProduct );
MsiGetProductProperty( hProduct, _T("ProductVersion"), pszVersion, &dwSizeVersion );
MsiCloseHandle( hProduct );
(обработка ошибок опущена)