Note:
- As you point out in your own answer, special quoting requirements apply to
cocho.exe
's /ia
parameter.
- However, since you are using
Start-Process
, it is not the instructions from the linked page for PowerShell that apply in this case, but the ones for cmd.exe
(even though there is no shell involved in this invocation; however, like cmd.exe
, console applications themselves generally only understand "..."
quoting); that is, your -ArgumentList
string must end up containing the following verbatim, which is what the string passed to -ArgumentList
below achieves via embedded "
characters escaped as `"
(""
would work too):
"/D=""C:Program Filespackagename"""
Start-Process -Wait -FilePath "C:ProgramDatachocolateychoco.exe" `
-ArgumentList "install $ChocoPackage -ia `"/D=`"`"C:Program Filespackagename`"`"`" -y"
Only if you call choco.exe
directly from PowerShell do the PowerShell instructions apply ('/D=""C:Program Filespackagename""'
):
& "C:ProgramDatachocolateychoco.exe" install $ChocoPackage -ia '/D=""C:Program Filespackagename""' -y
As for what you tried:
What you passed to -ArgumentList
was composed of three directly adjoining string literals in the form " a "' b '" c "
, to use a simplified example (i.e., a double-quoted string right next to single-quoted string, right next to another double-quoted string).
However, PowerShell doesn't fully support implicit concatenation of directly adjoining string literals to form a single argument the way that POSIX-compatible shells such as bash
do; doing so results in the strings being passed as separate arguments, which caused your problem (Start-Process
saw extra positional parameters after -ArgumentList
it didn't expect).
To demonstrate the original problem with the simplified example:
PS> Write-Output " a "' b '" c "
a
b
c
That is, Write-Output
received string literals " a "
, ' b '
, and " c "
as 3 separate arguments (as implied by their appearing on their own line each).
Only if the first token is unquoted do you get a single string argument composed of it and subsequent quoted tokens:
# *Single* argument, because `a` is *unquoted*.
PS> Write-Output a' b '" c "
a b c
The same applies even if that first unquoted token is a (non-expression) variable reference (e.g., Write-Output $HOME/'folder 1'/"and more"
; see this answer for more information
If you do need to reliably form a single string argument from a mix of double-quoted (interpolating) and single-quoted (verbatim) string literals, use (...)
, the grouping operator, and the +
operator for explicit string concatenation:
PS> Write-Output (" a " + ' b ' + " c ")
a b c
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…