Powershell - "InvokeMember" "5"参数错误



我一直遇到一个InvokeMember,有5个参数错误,但我认为这与我的路径有关。我想在脚本文件夹所在的任何位置的任何计算机上运行此程序。

$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 = "$ScriptDirProgram.exe"
Version = (get-item "$ScriptDirProgram.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
}
  • 您需要将.msi文件的完整文件系统本机路径传递给WindowsInstaller.InstallerCOM对象(Windows Installer COM Automation接口,因为PowerShell的当前目录(位置(通常与其他进程内环境(即.NET和COM使用的非托管进程(不同。

    • 虽然$FullPath = (Resolve-Path $fn).Path是从潜在的相对路径中获取完整路径的尝试,但它并不健壮,因为解析的路径可能基于仅限PowerShell的驱动器(使用New-PSDrive创建(,而外界对此一无所知。

    • 相反,使用Convert-Path-LiteralPath $fn,它返回文件系统本机路径,这是所有环境都知道的。

    • 在任何一种情况下,解析都基于当前位置,如$PWD/Get-Location所示。

  • 不需要通过.GetType().InvokeMember()使用反射来调用方法和访问Windows Installer COM对象公开的类型实例的属性-只需像往常一样直接调用/访问即可。(事实上,我无法让你的基于反射的代码工作。(

因此,以下内容应该有效:

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 $_
}
}

我目前不确定你的目标是什么,但如果你想接收有关MSIpackage的信息,你可以这样做:

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}

相关内容

  • 没有找到相关文章

最新更新