简体   繁体   中英

system call issue in C program on Windows

From within a C program I am trying to build a string that will be used in a system call:

   char myCommands[128];
   ...
   /* packing myCommands string */
   ..
   system(myCommands);

The command string to execute looks like this:

  setEnvVars.bat & xCmd.exe ...command-paramters...

If "...command-parameters..." does not contain any quote characters, all is well and statements succeed.

If "...command-parameters..." contains any quote characters I get this error:

  The filename, directory name, or volume label syntax is incorrect.

Example:

  setEnvVars.bat & xCmd.exe -e "my params with spaces"

Another odd thing, if I put the myCommands string into a *.bat file verbatim, quotes and all it works perfectly.

What is "system(...)" doing different?

== OK, More details ==

I have a simple program that demonstrates the problem. This version does work:

#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);
}

Outputs:

"C:\Windows\system32\cmd.exe" /c echo nospaces & C:\Windows\system32\cmd.exe /c echo moretext
nospaces
moretext

This does not work:

#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);
}

Outputs:

"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.

I think it may relate to the "cmd.exe /S" option, but trying to introduce that option does not change the behavior.

The quotes around the cmd.exe path are not needed because there is no space, but in my target program I am trying to allow all installation paths, which may include "C:\\Program Files"

(A pox on the person that that thought having spaces in path names was a good idea.)

(And using single quotes does not change the behavior.)

After banging my head a while, I abandoned the "system(cmdLine)" approach and went with a "CreateProcess" call (this will run under Windows).

Using CreateProcess I was able to side step the whole environment variable problem, which is what was leading me to try to use the "cmd1 & cmd2" syntax.

CreateProcess will allow you to pass a different environment to the child process. I was able to figure out how to rewrite the environment and pass that to the child. This neatly solved my issues.

My code to rewrite the environment may be a bit cumbersome but it works and seems fairly robust.

As you probably know, single quotes are for one character, and double are for multiple... You also are aware that you cannot contain double quotes inside a string, or it exits the string and adds them (depending on the situation)...

Try the following and tell what happens:

system("setEnvVars.bat & xCmd.exe -e 'my params with spaces'");

system("setEnvVars.bat & xCmd.exe -e \"my params with spaces\"");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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