这个参数在c#中是如何传递的?
本文关键字:何传递 参数 | 更新日期: 2023-09-27 17:49:59
我看过这段代码,但不太明白为什么它能成功运行。
class Program
{
public static void Main()
{
var startInfo = new ProcessStartInfo
{
FileName = "PowerShell.exe",
Arguments = @"-NoLogo -NoProfile ""Get-Content Queries.txt"" | Set-Content Output.tsv"
};
Console.WriteLine(startInfo.Arguments);
Process.Start(startInfo);
}
}
如果我尝试在命令提示符中直接执行powershell -NoLogo -NoProfile "Get-Content Queries.txt" | Set-Content Output.tsv
,它会抛出错误消息,但上面的代码片段可以成功完成。
代码中的双引号是如何处理的?
你说的命令提示符是指cmd.exe吗?如果是这样,您正在处理cmd.exe的解析,它不能很好地处理|
,例如:
C:'>dir | foo.txt
'foo.txt' is not recognized as an internal or external command,
operable program or batch file.
如果我在PowerShell V4提示符中尝试您的命令,它可以正常工作。此外,在c#中执行的脚本使用PowerShell的命令行解析,而不是cmd.exe的解析。
命令行参数使用空格作为分隔符进行解析,这当然可能是一个问题,例如具有空格的路径,例如Get-Content Queries.txt
。因此,为了解决这个问题,任何用双引号括起来的参数都将避免这种以空格分隔符进行解析。
那么为什么双引号可以工作呢?
对于所讨论的代码,因为字符串以@
字符串文字为前缀,所以允许不转义的双引号。关于@
字符串文字修饰符如何工作的一个很好的简短帖子(由Jon Skeet撰写)可以在字符串文字开始之前的@是什么意思?引用其中的一句话:
它的基本意思是,"在到达下一个引号字符之前,不要对字符进行任何解释"。因此,一个完整的字符串字面值可以包含反斜杠(不需要将它们加倍),甚至可以包含行分隔符。要在逐字文本中获得双引号("),您只需将其双引号括起来…
但是手动复制到命令行不工作,有什么不同?
因此,当将其复制到命令行时,这将不会以完全相同的方式工作,因为它不包括Process.Start()
在将参数包装在(等待它…)另一个引号中所采取的额外步骤!如PowerShell和命令行上的双引号所述:
下面是一些使其正常工作的方法:
使用单引号:
powershell.exe C:'Scripts'ParamCheck.ps1 -Something 'one two'
使用反斜杠分隔符(即使PowerShell内部使用left-single-quote"):
powershell.exe C:'Scripts'ParamCheck.ps1 -Something '"one two'"
使用三个双引号:
powershell.exe C:'Scripts'ParamCheck.ps1 -Something """one two"""
引用:
- 字符串字面值开始前的@是什么意思?
- PowerShell和命令行的双引号
- 什么时候我必须把双引号在参数值周围?