2014-03-12 36 views
1

我已經看過這個代碼片段,但不能完全弄清楚爲什麼它可以成功運行。這個參數是如何在C#中傳遞的?

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

嘗試提供Queries.txt的完整路徑 – cheedep

+0

@cheedep執行此操作時收到的錯誤消息是'Set-Content'不被識別爲內部或外部命令, 可操作程序或批處理文件。所以我認爲它與命令參數解析相關,而不是輸入文件的相對位置。 – derekhh

+0

相當於你在命令行上用C#做的事情是'powershell'-NoLogo -NoProfile「」Get-Content Queries.txt「」| Set-Content Output.tsv「' –

回答

0

命令行參數使用空格作爲分隔符進行分析,當然這可能是一個問題,例如有空格的路徑, Get-Content Queries.txt。所以爲了解決這個問題,用雙引號括起來的任何參數將避免這種類型的空間分隔符。

那麼,爲什麼雙引號的工作?

由於該代碼存在問題,因爲字符串前綴爲@字符串字面值,所以允許雙引號不轉義。有關@字符串文字修飾符如何工作(Jon Skeet不少於)的一篇很好的短文可以在What does an @ before the start of a string literal mean?找到。引述一個句子:

It basically means, "don't apply any interpretations to characters until the next quote character is reached". So, a verbatim string literal can contain backslashes (without them being doubled-up) and even line separators. To get a double-quote (") within a verbatim literal, you need to just double it...

但複製到命令行手動不起作用,有什麼不同?

因此,當將其複製到命令行時,它將不會以完全相同的方式工作,因爲它不包括Process.Start()在將參數封裝在其中的額外步驟(等待它...)另一個報價!正如PowerShell and double quotes on the command line描述:

Here’s some ways to make this work properly:

  • Use single quotes:

    powershell.exe C:\Scripts\ParamCheck.ps1 -Something 'one two'

  • Use a backslash delimiter (even though PowerShell internally uses the left-single-quote `):

    powershell.exe C:\Scripts\ParamCheck.ps1 -Something \"one two\"

  • Use three double quotes:

    powershell.exe C:\Scripts\ParamCheck.ps1 -Something """one two"""

參考文獻:

+0

謝謝。但爲什麼C#代碼可以成功執行呢? – derekhh

+0

更新了答案。這是因爲'@'文字。 –

+0

感謝您的詳細解釋,馬特。讓我試着更好地提出我的問題。我理解逐字逐字以及C#中這個參數是如何被解釋的。所以如果我理解正確的話,PowerShell.exe的參數應該是-NoLogo -NoProfile「Get-Content Queries.txt」| Set-Content Output.tsv – derekhh

1

當你說命令提示符下,你的意思CMD。可執行程序?如果是這樣,你正在處理的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的解析。