Powershell“找不到接受参数的位置参数”

问题描述

我在尝试运行此代码时遇到以下错误,但不知道如何解决。任何想法?

$Chocopackage = "packagename"
$localprograms = choco list --localonly
start-process -Wait -FilePath "C:\ProgramData\chocolatey\choco.exe" -ArgumentList "install $Chocopackage -ia "'/D=C:\Program Files\packagename'" -y"
start-process : A positional parameter cannot be found that accepts argument '/D=C:\Program Files\packagename'.
At C:\Program Files\install.ps1:3 char:5
+     start-process -Wait -FilePath "C:\ProgramData\chocolatey\choco.ex ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [start-process],ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.StartProcessCommand

解决方法

注意:

  • 正如您在自己的回答中指出的那样,special quoting requirements 适用于 cocho.exe/ia 参数。
  • 但是,由于您使用的是 Start-Process不是PowerShell 链接页面中的说明适用于这种情况,但是cmd.exe 的那些(尽管此调用中没有 shell;但是,像 cmd.exe 一样,控制台应用程序本身通常只理解 {{1} } 引用);也就是说,您的 "..." 字符串必须以包含以下 verbatim 结尾,这就是传递给下面 -ArgumentList 的字符串通过嵌入的 -ArgumentList 字符转义为 { {1}}(" 也可以):
    `"
""

仅当您从 PowerShell 直接调用 "/D=""C:\Program Files\packagename""" 时,PowerShell 说明才适用 (Start-Process -Wait -FilePath "C:\ProgramData\chocolatey\choco.exe" ` -ArgumentList "install $ChocoPackage -ia `"/D=`"`"C:\Program Files\packagename`"`"`" -y" ):

choco.exe

至于你尝试了什么

您传递给 '/D=""C:\Program Files\packagename""' 的内容由 三个& "C:\ProgramData\chocolatey\choco.exe" install $ChocoPackage -ia '/D=""C:\Program Files\packagename""' -y 形式直接相邻的字符串文字组成,使用一个简化的示例(即双引号右在单引号字符串旁边,在另一个双引号字符串旁边)。

但是,PowerShell 不完全支持隐式直接连接字符串文字的串联以形成单个参数,就像与 POSIX 兼容的 shell(例如 {{1} } 做;这样做会导致字符串作为 separate 参数传递,这导致了您的问题(-ArgumentList" a "' b '" c " 之后看到了它没想到的额外位置参数)。

使用简化示例演示原始问题:

bash

也就是说,Start-Process 接收字符串文字 -ArgumentListPS> Write-Output " a "' b '" c " a b c Write-Output 作为 3 个单独的参数(正如它们各自出现在自己的行中所暗示的那样)。

仅当第一个标记未加引号时,您才会得到一个单个字符串参数,由它和后续标记组成引用标记:

" a "

即使第一个未加引号的标记是(非表达式)变量引用(例如,' b ';有关详细信息,请参阅 this answer),同样适用


如果您确实需要从双引号(插值)和单引号(逐字)字符串文字的混合中可靠地形成单个字符串参数,请使用 " c " grouping operator# *Single* argument,because `a` is *unquoted*. PS> Write-Output a' b '" c " a b c 运算符用于显式字符串连接

Write-Output $HOME/'folder 1'/"and more"
,

哦,当然,我在阅读了 Chocolatey 官方文档后几乎立即就明白了。由于我使用的是 powershell,因此您必须非常具体地将空格括在引号中。

-ia '/yo=""Spaces spaces""'

https://docs.chocolatey.org/en-us/choco/commands/#how-to-pass-options-switches

在参数中传递引号:当您需要将带引号的值传递给诸如本机安装程序之类的东西时,您将进入一个有趣的世界。在 cmd.exe 中,您必须像这样传递它:-ia "/yo=""Spaces space"""。在 PowerShell.exe 中,您必须像这样传递它:-ia '/yo=""Spaces space""'。没有其他组合将起作用。在 PowerShell.exe 中,如果您使用的是 v3+ 版本,则可以在 -ia 之前尝试 --% 以按原样传递参数,这意味着它不需要任何特殊的解决方法。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...