我经常遇到一个带有5个参数错误的InvokeMember,但我相信这与我的路径有关。我想从脚本文件夹所在的任何位置从任何计算机运行此命令。
$ScriptDir = Split-Path $MyInvocation.MyCommand.Path
$ScriptName = $MyInvocation.MyCommand.Name
Function Get-MsiDBVersion {
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) | Out-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) | Out-Null
return $productVersion
} catch {
throw "Failed to get MSI file version the error was: {0}." -f $_
}
}
$Program = @{
Installer = "$ScriptDir\Program.exe"
Version = (get-item "$ScriptDir\Program.exe").VersionInfo.FileVersion.TrimEnd()
Arguments = "/SILENT /ALLUSERS /NORESTART"
Exe = "C:\Program Files (x86)\Program.exe"
ExeVersion = (Get-ChildItem $RegUninstall32 -ErrorAction SilentlyContinue | where name -like "*program*" | Get-ItemProperty ).DisplayVersion
}发布于 2022-09-07 14:55:15
.msi文件到WindowsInstaller.Installer COM对象(Windows安装程序COM自动化接口 ),因为PowerShell的当前目录(位置)通常不同于其他进程内环境,即.NET和COM使用的非托管进程。- While `$FullPath = (Resolve-Path $fn).Path` is an _attempt_ to get the full path from a potentially relative one, it isn't _robust_, because the resolved path may be based on a _PowerShell-only_ drive (created with `New-PSDrive`), which the outside world knows nothing about.- Instead, use [`Convert-Path`](https://learn.microsoft.com/powershell/module/microsoft.powershell.management/convert-path) `-LiteralPath $fn`, which returns a _file-system-native_ path, as known to all environments.- In either case, the resolving is based on the _current location_, as reflected in `$PWD` / `Get-Location`..GetType().InvokeMember()使用反射来调用方法并访问Windows对象公开的类型的实例的属性--照例直接调用/访问它们。(实际上,我无法让基于反射的代码工作。)因此,下列各项应能发挥作用:
Function Get-MsiDBVersion {
param (
[string] $LiteralPath
)
try {
# Convert to a full, native path.
$fullPath = Convert-Path -ErrorAction Stop -LiteralPath $LiteralPath
$windowsInstaller = New-Object -ComObject WindowsInstaller.Installer
$database = $windowsInstaller.Opendatabase($fullPath, 0)
$q = "SELECT Value FROM Property WHERE Property = 'ProductVersion'"
$view = $database.OpenView($q)
$null = $View.Execute()
$record = $View.Fetch()
$productVersion = $record.StringData(1)
$null = $View.Close()
return $productVersion
}
catch {
throw "Failed to get MSI file version; the error was: {0}." -f $_
}
}发布于 2022-09-07 06:35:01
我不知道您目前的目标是什么,但是如果您想获得有关MSIpackages的信息,可以这样做:
Get-CimInstance -query "select * from win32_product"您的查询不起作用--您的代码:
$q = "SELECT Value FROM Property WHERE Property = 'ProductVersion'"语法必须是:
"Select [Property] from [class] where [property] = [propertyvalue]"例如:
get-ciminstance -query "select version,installState,Description,version,IdentifyingNumber from win32_product where Name = 'Blender'"产出:
Name : Blender
Version : 2.82.1
InstallState : 5
Caption :
Description : Blender
IdentifyingNumber : {EDFAE2A8-E73B-4CD1-9648-46A7E4434BDA}https://stackoverflow.com/questions/73629365
复制相似问题