簡體   English   中英

如何使用 PowerShell 查找 MSI 產品版本號?

[英]How do I find the MSI product version number using 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,就不應該有這個問題。

編輯:

這里有一些 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 (
        [string] $fn
    )

    try {
        $FullPath = (Resolve-Path $fn).Path
        $windowsInstaller = New-Object -com WindowsInstaller.Installer

        $database = $windowsInstaller.GetType().InvokeMember(
                "OpenDatabase", "InvokeMethod", $Null, 
                $windowsInstaller, @($FullPath, 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 "Installer.msi"

(對不起,沒有代表只是在接受的答案中添加評論)

@davidmartin 的回答對我很有幫助。

我需要添加的唯一一點是在返回版本之前關閉對象,否則 msi 上的句柄保持打開狀態,以后訪問可能會失敗:

$View.GetType().InvokeMember("Close", "InvokeMethod", $Null, $View, $Null)

return $productVersion

PowerShell 模塊“Carbon”非常適合做這件事。

幾年前,我在使用 PowerShell Desired State Configuration (DSC) 進行大量工作時發現了它,它需要安裝 MSI 的產品代碼(guid)。 如果應用程序安裝在計算機上,則可以使用 PowerShell 本地獲取產品代碼,與版本號相同,但 Carbon 可以從 MSI 中獲取。

http://get-carbon.org/

Import-Module -Name Carbon
Get-MSI -Path C:\PathToMSI

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM