【问题标题】:command line arguments given to a C# program are parsed wrong给 C# 程序的命令行参数解析错误
【发布时间】:2016-08-07 05:39:19
【问题描述】:

我写了一个小程序,例如有如下命令行:

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

一个可能的解决方案是检查调用应用程序中的文件和路径名称是否包含空格,然后才在名称周围附加引号。

但是还有其他解决方案吗?

【问题讨论】:

  • 有很多很好的库来解决命令行参数,它们也给你解析、帮助、强制参数检查等等。我建议您查看其中之一,而不是推出自己的解决方案。一个例子是github.com/gsscoder/commandline

标签: c# parsing command arguments line


【解决方案1】:

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

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,我相信这是对命令行解析的一般问题的最终答案。

【讨论】:

  • 更新了答案的文本。恐怕没有“标准”。
  • 我认为,在我的情况下,根据需要添加引号和/或转义反斜杠字符是最简单的方法。
猜你喜欢
  • 2018-05-15
  • 1970-01-01
  • 2013-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多