简体   繁体   English

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

[英]command line arguments given to a C# program are parsed wrong

I wrote a little program, that has the following command line for example: 我编写了一个小程序,例如,具有以下命令行:

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

This command line is being generated by another program that inserts the quotation marks around the file and path names automatically to prevent spaces being recognized as argument separators. 该命令行由另一个程序生成,该程序会自动在文件名和路径名周围插入引号,以防止空格被识别为参数分隔符。

The first command line is then being parsed by the .Net framework as: 然后,.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

But it should be ( the result from the second command line): 但这应该是(第二个命令行的结果):

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

A possible solution would be to check the file and path names in the calling application if they contain spaces and only then append the quotation marks around the names. 可能的解决方案是检查调用应用程序中的文件名和路径名是否包含空格,然后仅在名称周围加上引号。

But is there another solution? 但是还有其他解决方案吗?

I created a little batch file that would display the command line parameters. 我创建了一个小的批处理文件,该文件将显示命令行参数。 With your first command line, I get 用你的第一个命令行,我得到

1 -p
2 -z
3 "E:\temp.zip"
4 -v
5 "f:\"
6 -r
7 -o
8 -s
9 –c

as it should. 正如它应该。 If .NET parses it differently, that would be a major bug. 如果.NET用不同的方式解析它,那将是一个主要的错误。 Just to check, I created a test console app. 为了检查,我创建了一个测试控制台应用程序。 The results were: 结果是:

0  -p
1  -z
2  E:\temp.zip
3  -v
4  f:" -r -o -s -c

I didn't think that was possible! 我认为那是不可能的! So I researched a little and I got to this link: Everyone quotes command line arguments the wrong way which explains why the command line parser is essentially flawed. 因此,我做了一些研究,然后进入了此链接: 每个人都以错误的方式引用命令行参数,这解释了为什么命令行解析器本质上是有缺陷的。 (I know it's for C++, but it applies) which led me to the rules of parsing for command line parameters which says \\" is interpreted as an escaped quote, as opposed to how the operating system sees it (which is gross). (我知道这是针对C ++的,但是它适用),这使我想到了解析命令行参数的规则,规则说\\“被解释为转义的引号,而不是操作系统如何看待它(这很重要)。

Conclusion: if you want to fix the command line, you need to escape the slash before a quote so instead of "f:\\" you need "f:\\\\" . 结论:如果要修复命令行,则需要在引号前转义斜杠,因此需要"f:\\\\"而不是"f:\\" "f:\\\\" The other solution is to use Environment.CommandLine which gets you the entire command line, executable included, and you can parse it yourself. 另一种解决方案是使用Environment.CommandLine ,它为您提供了整个命令行(包括可执行文件),您可以自己解析它。 More on this here: Getting raw (unsplit) command line in .NET . 有关更多信息,请参见:在.NET中获取原始(未拆分)命令行

Just for completeness' sake, I'll throw this in: Split string containing command-line parameters into string[] in C# , which discusses how to split a command line string into parameters using system functions. 出于完整性考虑,我将其投入以下内容: 在C#中 ,将包含命令行参数的字符串拆分为string [] ,其中讨论了如何使用系统函数将命令行字符串拆分为参数。

After some more research, I realized that there are several standards of command line argument parsing, depending on compiler and operating system and its version, and that the only way to be consistent is to parse the raw command line yourself. 经过更多研究后,我意识到命令行参数解析有多种标准,具体取决于编译器和操作系统及其版本,唯一的一致方法是自己解析原始命令行。

For example, using CommandLineToArgvW on Environment.CommandLine replicated exactly a call to Environment.GetCommandLineArgs() which returns the exact same thing as the args array given to the Main method. 例如,在Environment.CommandLine上使用CommandLineToArgvW,可以完全复制对Environment.GetCommandLineArgs()的调用,该调用将返回与给Main方法的args数组完全相同的东西。

I found a very detailed page about this problem: http://daviddeley.com/autohotkey/parameters/parameters.htm which I believe is the definitive answer to the general question of command line parsing. 我找到了一个有关此问题的非常详细的页面: http : //daviddeley.com/autohotkey/parameters/parameters.htm ,我相信这是对命令行解析的一般性问题的明确答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM