[英]command line arguments given to a C# program are parsed wrong
我編寫了一個小程序,例如,具有以下命令行:
prog.exe -p -z "E:\temp.zip" -v "f:\" -r -o -s –c
prog.exe -p -z "E:\temp.zip" -v f:\ -r -o -s –c
prog.exe -p -z "E:\temp.zip" -v "f:\log" -r -o -s –c
該命令行由另一個程序生成,該程序會自動在文件名和路徑名周圍插入引號,以防止空格被識別為參數分隔符。
然后,.Net框架將第一個命令行解析為:
args {string[5]} string[]
[0] "-p" string
[1] "-z" string
[2] "f:\\temp.zip" string
[3] "-v" string
[4] "f:\" -r -o -s -c" string
但這應該是(第二個命令行的結果):
args {string[9]} string[]
[0] "-p" string
[1] "-z" string
[2] "f:\\temp.zip" string
[3] "-v" string
[4] "f:\\" string
[5] "-r" string
[6] "-o" string
[7] "-s" string
[8] "-c" string
可能的解決方案是檢查調用應用程序中的文件名和路徑名是否包含空格,然后僅在名稱周圍加上引號。
但是還有其他解決方案嗎?
我創建了一個小的批處理文件,該文件將顯示命令行參數。 用你的第一個命令行,我得到
1 -p
2 -z
3 "E:\temp.zip"
4 -v
5 "f:\"
6 -r
7 -o
8 -s
9 –c
正如它應該。 如果.NET用不同的方式解析它,那將是一個主要的錯誤。 為了檢查,我創建了一個測試控制台應用程序。 結果是:
0 -p
1 -z
2 E:\temp.zip
3 -v
4 f:" -r -o -s -c
我認為那是不可能的! 因此,我做了一些研究,然后進入了此鏈接: 每個人都以錯誤的方式引用命令行參數,這解釋了為什么命令行解析器本質上是有缺陷的。 (我知道這是針對C ++的,但是它適用),這使我想到了解析命令行參數的規則,該規則說\\“被解釋為轉義的引號,而不是操作系統如何看待它(這很重要)。
結論:如果要修復命令行,則需要在引號前轉義斜杠,因此需要"f:\\\\"
而不是"f:\\"
"f:\\\\"
。 另一種解決方案是使用Environment.CommandLine ,它為您提供了整個命令行(包括可執行文件),您可以自己解析它。 有關更多信息,請參見:在.NET中獲取原始(未拆分)命令行 。
出於完整性考慮,我將其投入以下內容: 在C#中 ,將包含命令行參數的字符串拆分為string [] ,其中討論了如何使用系統函數將命令行字符串拆分為參數。
經過更多研究后,我意識到命令行參數解析有多種標准,具體取決於編譯器和操作系統及其版本,唯一的一致方法是自己解析原始命令行。
例如,在Environment.CommandLine上使用CommandLineToArgvW,可以完全復制對Environment.GetCommandLineArgs()的調用,該調用將返回與給Main方法的args數組完全相同的東西。
我找到了一個有關此問題的非常詳細的頁面: http : //daviddeley.com/autohotkey/parameters/parameters.htm ,我相信這是對命令行解析的一般性問題的明確答案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.