拼写一个标签 - 启动过程-argumentList



我正在尝试使用剥落安装.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样式

最新更新