我正在尝试使用剥落安装.msi:
$InstallerArgs @{
"DATABASENAME" = "my_database";
"LOCALIP" = "127.0.0.1";
"USERNAME" = "username1";
"/i" = "C:FilesInstaller.msi";
}
我然后致电Start-Process:
Start-Process -FilePath msiexec.exe -ArgumentList @InstallerArgs -Wait
这返回错误:Missing an argument for parameter 'ArgumentList'. Specify a parameter of type 'System.String[]' and try again.
不可能使用Start-Process
?
splatting( @<varName>
(不支持参数 value (参数(;取而代之的是,张力本身代表一组参数 name-value pairs 。。
OLAF的有用答案证明了碎片的适当使用,其中标题包含整个Start-Process
的参数名称值对,并与通行直通msiexec
参数指定为ArgumentList
Hashtable条目中的数组。
如果您确实想在单独的数据结构中仅维护通过传递到 msiexec
参数,请使用 array 和以这样的方式传递-ArgumentList
确实期望字符串 array 作为其参数([string[]]
(:
$InstallerArgs = @(
"DATABASENAME=my_database"
"LOCALIP=127.0.0.1"
"USERNAME=username1"
"/i"
"C:FilesInstaller.msi"
)
# Note: NO splatting
Start-Process -FilePath msiexec.exe -ArgumentList $InstallerArgs -Wait
上面的结尾执行以下执行:
msiexec.exe DATABASENAME=my_database LOCALIP=127.0.0.1 USERNAME=username1 /i C:FilesInstaller.msi
请注意,由于长期存在 bug ,任何需要 double Quoting 的值,通常是因为它们已经嵌入了 whitespace - 必须明确指定嵌入式,逃脱 double引号以及( `"
(;例如,
"`"C:Files AInstaller.msi`""
这将导致msiexec ... "C:Files AInstaller.msi"
通过。
问题仍然存在于PowerShell [core] 7.0,并且可能永远不会修复以保持向后兼容性。但是,可以提供一个新的参数以提供正确的行为 - 请参见GitHub问题#5576。
警告用外部程序:
用 hashtables (而不是数组(时,PowerShell将Hashtable条目转换为
-<key>:<value>
参数 - 注意与 powerShell 命令效果很好的 :
-但可能不符合外部实用程序所期望的参数语法,例如 msiexec
。
GitHub问题#9343建议将格式更改为用a space 分离(使用单独的参数; -<key> <value>
(。
一个简单的示例:
# Define hashtable with parameter name-value pairs.
$htParams = @{
foo = 'bar none' # parameter -foo with value 'bar none'
}
# Pass the hashtable via splatting (note the use of @ instead of $).
baz.exe @htParams
baz.exe
然后会看到以下参数:
-foo:"bar none"
这应该有效:
$InstallerArgs = @{
FilePath = 'msiexec.exe'
ArgumentList = @(
'/i',
'C:FilesInstaller.msi',
'LOCALIP="127.0.0.1"',
'USERNAME="username1"'
)
Wait = $True
}
Start-Process @InstallerArgs
您不一定需要Start-Process
。请记住:Powershell是壳;它可以运行您键入的命令,就像cmd.exe
一样。
msiexec /i C:FilesInstaller.msi DATABASENAME=my_database LOCALIP=127.0.0.1 USERNAME=username1
如果任何参数包含空间,请将它们包装在"
字符中。
注意:这将异步运行msiexec
(即,如果您以脚本运行命令,它将继续到下一行脚本,而无需等待msiexec
完成(。如果要等待msiexec
在继续之前完成(即同步运行(,则可以在其他答案中指出的Start-Process
与-Wait
参数一起使用。
此解决方案仅在您有键= value pairs
时起作用$params = [string]::Join(" ", ($parameters.GetEnumerator() | ForEach-Object { $_.Key + "=" + $_.Value }))
Start-Process -FilePath msiexec.exe -ArgumentList @InstallerArgs -Wait
我是C#DEV,所以它可能不是常规的PS样式