В нашей конечной версии есть много файлов MSI.
Я бы удостоверился, что у них есть правильное название продукта и версия продукта.
Я использую Orca и делаю это вручную.
Как это сделать с помощью PowerShell?
В нашей конечной версии есть много файлов MSI.
Я бы удостоверился, что у них есть правильное название продукта и версия продукта.
Я использую Orca и делаю это вручную.
Как это сделать с помощью PowerShell?
Это должно было быть легким ответом... Для начала с Windows Installer есть COM-объект, вы можете использовать:
ProgID: WindowsInstaller.Installer
Однако, когда вы создаете объект из PowerShell, вы не получаете никаких свойств или методов:
$object = New-Object -Com WindowsInstaller.Installer
$object | gm
... Ничего: - (
По-видимому, это проблема с системой PowerShell и ее адаптационной системой. См. Это сообщение в блоге для работы.
http://www.snowland.se/2010/02/21/read-msi-information-with-powershell/
Если вы используете VBScript, у вас не должно быть этой проблемы.
EDIT:
Вот какой VBScript, который получит версию я найденный:
Const msiOpenDatabaseModeReadOnly = 0
Dim msi, db, view
Set msi = CreateObject("WindowsInstaller.Installer")
Set db = msi.OpenDataBase("C:\Users\andy\Desktop\Module.msi", msiOpenDatabaseModeReadOnly)
Set view = db.OpenView("SELECT `Value` FROM `Property` WHERE `Property` = 'ProductVersion'")
Call view.Execute()
GetVersion = view.Fetch().StringData(1)
Wscript.Echo GetVersion
Вы можете вызвать это из PowerShell:
$version = & cscript.exe /nologo GetVersion.vbs
Обновить! Проблема адаптации этого типа меня разочаровывала, и я не был доволен решением VBS. После небольшого исследования я нашел способ сделать это в PowerShell. Я адаптировал код из его записи в блоге. Наслаждайтесь!
function Get-MsiDatabaseVersion {
param (
[IO.FileInfo] $FilePath
)
try {
$windowsInstaller = New-Object -com WindowsInstaller.Installer
$database = $windowsInstaller.GetType().InvokeMember(
"OpenDatabase", "InvokeMethod", $Null,
$windowsInstaller, @($FilePath.FullName, 0)
)
$q = "SELECT Value FROM Property WHERE Property = 'ProductVersion'"
$View = $database.GetType().InvokeMember(
"OpenView", "InvokeMethod", $Null, $database, ($q)
)
$View.GetType().InvokeMember("Execute", "InvokeMethod", $Null, $View, $Null)
$record = $View.GetType().InvokeMember(
"Fetch", "InvokeMethod", $Null, $View, $Null
)
$productVersion = $record.GetType().InvokeMember(
"StringData", "GetProperty", $Null, $record, 1
)
$View.GetType().InvokeMember("Close", "InvokeMethod", $Null, $View, $Null)
return $productVersion
} catch {
throw "Failed to get MSI file version the error was: {0}." -f $_
}
}
Get-MsiDatabaseVersion "C:\Installer.msi"
(Извините, у меня нет ответа, чтобы просто добавить комментарий к принятому ответу)
Ответ от @davidmartin был очень полезен для меня.
Только бит, который мне нужно было добавить, заключался в том, чтобы закрыть объект перед возвратом версии, иначе дескриптор будет открыт на msi, и позже доступ может завершиться неудачно:
$View.GetType().InvokeMember("Close", "InvokeMethod", $Null, $View, $Null)
return $productVersion