我编写了一个小程序,其中包含以下命令行:
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
一种可能的解决方案是检查调用应用程序中的文件和路径名称(如果它们包含空格),然后在名称后附加引号。
但还有另一种解决方案吗?
答案 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我相信这是对命令行解析的一般问题的明确答案。