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

时间:2015-08-21 22:28:39

标签: c++ c windows createprocess

将命令行参数传递给Linux中的应用程序只需使用exec *命令就可以正常工作,您可以在其中清楚地传递每个参数。如果想要控制标准管道,则无法在Windows上使用相同的功能执行此操作。由于这些函数基于CreateProcess(),are some clear rules有关如何转义特殊字符(如双引号)的问题。

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

这意味着一个名为test的简单应用程序使用main()作为入口点得到" abc"如果被称为test.exe \"abc\"。将cmd.exe称为cmd.exe /c "echo \"abc\""将不会输出" abc"正如预期的那样,但是\" abc \"。

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

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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

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

但是,在您的方案中(如评论中所述)不应该是一个问题。您所要做的就是确保向用户询问命令,而不是查询参数列表。你的程序根本不需要知道命令如何被分成参数,如果有的话;理解命令的语法是用户的工作。 [注意:如果你不认为这是真的,你需要更清楚地解释你的情景。提供一个示例,说明用户可能输入的内容以及您认为应用程序处理它的方式。]

PS:既然您提到了C库_exec功能,请注意它们不会像您期望的那样工作。这些论点不会单独传递给孩子,因为那是不可能的;在Microsoft C运行时,如果我没记错的话,参数只是简单地组合成一个字符串,只有一个空格作为分隔符,因此("hello there")将与("hello", "there")无法区分。

PPS:请注意,调用cmd.exe来解析命令会引入一个额外的(更复杂的)处理层。一般来说,考虑到这一点仍然是用户的工作,但您可能想要了解它。 cmd.exe处理的转义字符是插入符号。