Alan Penny
Alan Penny

Reputation: 182

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

Upvotes: 1

Views: 4321

Answers (2)

Alan Penny
Alan Penny

Reputation: 182

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.

Upvotes: 1

Mitch
Mitch

Reputation: 44

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\"");

Upvotes: 0

Related Questions