我已经看过这段代码片段,但无法弄清楚为什么它可以成功运行。
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
,它会抛出错误消息,但上面的代码片段可能会成功完成。
如何处理代码中的双引号?
答案 0 :(得分:1)
当你说命令提示符时,你的意思是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的解析。
答案 1 :(得分:0)
使用空格作为分隔符来解析命令行参数,这对于诸如具有空格的路径之类的事物当然是一个问题。 Get-Content Queries.txt
。因此,为了解决这个问题,用双引号括起来的任何参数都将避免这种类型的空格分析。
为什么双引号有效?
使用相关代码,因为字符串以@
字符串文字为前缀,所以允许双引号而不转义。关于@
字符串文字修饰符如何工作(由Jon Skeet不少)的简短帖子可以在What does an @ before the start of a string literal mean?找到。引用一句话:
它基本上意味着,“#”不会对字符应用任何解释,直到达到下一个引号字符为止#34;。因此,逐字字符串文字可以包含反斜杠(没有它们被加倍)甚至行分隔符。要在逐字逐句中获得双引号("),您需要加倍...
但是手动复制到命令行并不起作用,有什么不同?
因此,当将其复制到命令行时,这不会以完全相同的方式工作,因为它不包含Process.Start()
包装参数所需的额外步骤(等待对它...)另一个引用!如PowerShell and double quotes on the command line:
以下是使这项工作正常运行的一些方法:
使用单引号:
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"""
<强>参考文献:强>