赋予C#程序的命令行参数被解析错误

时间:2016-04-15 09:54:10

标签: c# parsing command arguments line

我编写了一个小程序,其中包含以下命令行:

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 个答案:

答案 0 :(得分:2)

我创建了一个显示命令行参数的小批处理文件。使用第一个命令行,我得到了

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

我认为没有可能!所以我研究了一下,我得到了这个链接:Everyone quotes command line arguments the wrong way,这解释了为什么命令行解析器本质上是有缺陷的。 (我知道它适用于C ++,但它适用)导致我使用rules of parsing命令行参数,这些参数表示\"被解释为转义引用,而不是操作系统如何看待它(这是粗略的)。

结论:如果要修复命令行,则需要在引号之前转义斜杠,而不是"f:\"需要"f:\\"。另一种解决方案是使用Environment.CommandLine来获取整个命令行,包括可执行文件,您可以自己解析它。更多相关信息:Getting raw (unsplit) command line in .NET

只是为了完整性'为此,我将其放入:Split string containing command-line parameters into string[] in C#,其中讨论了如何使用系统函数将命令行字符串拆分为参数。

  

经过一些研究,我意识到有几个标准   命令行参数解析,取决于编译器和操作   系统及其版本,唯一的方法是保持一致   自己解析原始命令行。

例如,在Environment.CommandLine上使用CommandLineToArgvW完全复制了对Environment.GetCommandLineArgs()的调用,该调用返回与给予Main方法的args数组完全相同的内容。

我找到了一个关于这个问题的非常详细的页面:http://daviddeley.com/autohotkey/parameters/parameters.htm我相信这是对命令行解析的一般问题的明确答案。