关于C#:如何正确地将命令行参数传递给Windows应用程序?

How to pass command-line arguments to a Windows application correctly?

在Linux中将命令行参数传递给应用程序恰好与exec *命令配合使用,在该命令中您可以清楚地自行传递每个参数。如果要控制标准管道,则在Windows上使用相同功能的方法不是一种选择。由于这些函数基于CreateProcess(),因此对于如何转义特殊字符(如双引号)有一些明确的规则。

遗憾的是,只有在被调用的应用程序通过main(),wmain()或CommandLineToArgvW()检索其命令行参数时,此方法才能正常工作。但是,如果被调用的应用程序通过WinMain(),wWinMain(),GetCommandLineA()或GetCommandLineW()获取这些参数,则由应用程序决定如何解析命令行参数,因为它将获取整个命令行而不是参数根据参数。

这意味着使用main()作为入口点的名为test的简单应用程序如果被称为test.exe "abc",则将获得" abc"。以cmd.exe /c"echo "abc""身份调用cmd.exe不会按预期方式输出" abc",而是" abc "。

这引起了我的问题:尽管有这些怪癖,如何以通用方式将命令行参数传递给Windows应用程序?


在Windows中,您需要考虑整个命令,而不是单个参数的列表。应用程序没有义务以任何特定的方式或者根本不将命令解析为参数;考虑echo命令的示例,该示例将命令行视为单个字符串。

这对于运行时库开发人员可能是个问题,因为这意味着没有可靠的方法来实现类似POSIX的exec函数。一些库开发人员采用直接的方法,并要求程序员在必要时提供引号,而另一些库则尝试自动对参数进行引用。在后一种情况下,必须为程序员提供某种方法来整体指定命令行,从而禁用任何自动引号,即使这意味着Windows特定的扩展。

但是,在您的情况下(如评论中所述)应该没有问题。所有您需要做的就是确保您询问用户一个命令,而不是一个参数列表。您的程序根本不需要知道如何将命令拆分为参数。理解命令的语法是用户的工作。 [注意:如果您认为不正确,则需要更清楚地说明您的情况。提供一个示例,说明用户可能输入的内容以及您认为应用程序需要如何处理它。]

PS:由于您提到了C库_exec函数,因此请注意,它们无法正常运行。参数是不会单独传递给孩子的,因为这是不可能的。在Microsoft C运行时中,如果我没记错的话,将参数简单地组合在一起成为单个字符串,并以单个空格作为定界符,因此("hello there")("hello","there")是无法区分的。

PPS:请注意,调用cmd.exe来解析命令会引入附加的(并且要复杂得多)处理层。一般来说,考虑到这一点仍然是用户的工作,但是您可能要意识到这一点。 cmd.exe处理的转义字符是插入符号。


这是C语言,您需要在C代码中的双引号之前使用反斜杠。对于外壳处理,没有这样的规则。因此,如果您编写代码以调用CreateProcess并传递文字字符串"abc",则需要使用反斜杠,因为您是用C语言编写的。但是如果编写要传递的shell脚本,则应调用您的应用程序以传递"abc",例如例如Echo例子,那么您就不会使用反斜杠,因为其中不涉及C代码。