如何正确地将命令行parameter passing给Windows应用程序?

将命令行parameter passing给Linux中的应用程序可以很好地与exec *命令一起工作,在这些命令中,您清楚地传递了每个参数。 如果想要控制标准pipe道,则在Windows上使用相同function进行此操作不是一个选项。 由于这些函数是基于CreateProcess(),所以在如何转义特殊字符(如双引号)方面有一些明确的规则 。

不幸的是,只要被调用的应用程序通过main(),wmain()或者CommandLineToArgvW()来获取它的命令行参数,这只能正常工作。 但是,如果被调用的应用程序通过WinMain(),wWinMain(),GetCommandLineA()或GetCommandLineW()获取这些参数,则应用程序如何parsing命令行参数,因为它获取整个命令行而不是参数通过论点。

这意味着一个名为test的简单应用程序使用main()作为入口点,如果调用test.exe \"abc\"则会获得“abc test.exe \"abc\" 。 调用cmd.exe作为cmd.exe /c "echo \"abc\""将不会输出“abc”,而是\“abc \”。

这导致我的问题:
尽pipe有这些怪癖,如何以通用的方式将命令行parameter passing给Windows应用程序?

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

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

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

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

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

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