从一个C程序中,我试图build立一个系统调用中使用的string:
char myCommands[128]; ... /* packing myCommands string */ .. system(myCommands);
要执行的命令string如下所示:
setEnvVars.bat & xCmd.exe ...command-paramters...
如果“… command-parameters …”不包含任何引号字符,一切正常,语句成功。
如果“…命令参数…”包含任何引号字符,我得到这个错误:
The filename, directory name, or volume label syntax is incorrect.
例:
setEnvVars.bat & xCmd.exe -e "my params with spaces"
另一个奇怪的事情,如果我把myCommandsstring逐字地放进一个* .bat文件,引用和所有它完美的作品。
什么是“系统(…)”的不同?
== OK,更多细节==
我有一个简单的程序来演示这个问题。 这个版本确实有效:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { char cmdStr[1024]; strcpy(cmdStr, "\"C:\\Windows\\system32\\cmd.exe\" /c echo nospaces & C:\\Windows\\system32\\cmd.exe /c echo moretext"); printf("%s\n", cmdStr); system(cmdStr); }
输出:
"C:\Windows\system32\cmd.exe" /c echo nospaces & C:\Windows\system32\cmd.exe /c echo moretext nospaces moretext
这不起作用 :
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { char cmdStr[1024]; strcpy(cmdStr, "\"C:\\Windows\\system32\\cmd.exe\" /c echo nospaces & \"C:\\Windows\\system32\\cmd.exe\" /c echo moretext"); printf("%s\n", cmdStr); system(cmdStr); }
输出:
"C:\Windows\system32\cmd.exe" /c echo nospaces & "C:\Windows\system32\cmd.exe\" /c echo moretext The filename, directory name, or volume label syntax is incorrect.
我认为它可能涉及到“cmd.exe / S”选项,但试图介绍该选项不会改变行为。
cmd.exepath周围的引号是不需要的,因为没有空间,但在我的目标程序中,我试图允许所有的安装path,其中可能包括“C:\ Program Files”
(对那些认为在path名中有空格的人来说,这是一个好主意。)
(而使用单引号不会改变行为。)
在我敲了一下脑后,我放弃了“系统(cmdLine)”方法,并使用“CreateProcess”调用(这将在Windows下运行)。
使用CreateProcess,我能够侧退整个环境变量的问题,这正是导致我尝试使用“cmd1&cmd2”语法的原因。
CreateProcess将允许您将不同的环境传递给子进程。 我能够弄清楚如何改写环境并将其传递给孩子。 这整齐地解决了我的问题。
我的代码重写环境可能有点麻烦,但它的工作,似乎相当强大。
正如你可能知道的,单引号是一个字符,双是多个…你也知道你不能在一个字符串中包含双引号,或者退出字符串并添加它们(取决于情况)。 。
尝试以下,并告诉发生了什么:
system("setEnvVars.bat & xCmd.exe -e 'my params with spaces'"); system("setEnvVars.bat & xCmd.exe -e \"my params with spaces\"");