Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Way to pass argv[] to CreateProcess()

My C Win32 application should allow passing a full command line for another program to start, e.g.

myapp.exe /foo /bar "C:\Program Files\Some\App.exe" arg1 "arg 2"

myapp.exe may look something like

int main(int argc, char**argv)
{
  int i;

  for (i=1; i<argc; ++i) {
     if (!strcmp(argv[i], "/foo") {
        // handle /foo
     } else if (!strcmp(argv[i], "/bar") {
        // handle /bar
     } else {
        // not an option => start of a child command line
        break;
     }
  }

  // run the command
  STARTUPINFO si;
  PROCESS_INFORMATION pi;
  // customize the above...

  // I want this, but there is no such API! :(
  CreateProcessFromArgv(argv+i, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);

  // use startup info si for some operations on a process
  // ...
}

I can think about some workarounds:

  • use GetCommandLine() and find a substring corresponding to argv[i]
  • write something similar to ArgvToCommandLine() also mentioned in another SO question

Both of them lengthy and re-implement cumbersome windows command line parsing logic, which is already a part of CommandLineToArgvW().

Is there a "standard" solution for my problem? A standard (Win32, CRT, etc.) implementation of workarounds counts as a solution.

like image 601
Ilia K. Avatar asked Oct 20 '10 21:10

Ilia K.


2 Answers

It's actually easier than you think.

1) There is an API, GetCommandLine() that will return you the whole string

myapp.exe /foo /bar "C:\Program Files\Some\App.exe" arg1 "arg 2"

2) CreateProcess() allows to specify the command line, so using it as

CreateProcess(NULL, "c:\\hello.exe arg1 arg2 etc", ....) 

will do exactly what you need.

3) By parsing your command line, you can just find where the exe name starts, and pass that address to the CreateProcess() . It could be easily done with

char* cmd_pos = strstr(GetCommandLine(), argv[3]);

and finally: CreateProcess(NULL, strstr(GetCommandLine(), argv[i]), ...);

EDIT: now I see that you've already considered this option. If you're concerned about performance penalties, they are nothing comparing to process creation.

like image 145
ruslik Avatar answered Sep 17 '22 18:09

ruslik


The only standard function which you not yet included in your question is PathGetArgs, but it do not so much. The functions PathQuoteSpaces and PathUnquoteSpaces can be also helpful. In my opinion the usage of CommandLineToArgvW in combination with the with GetCommandLineW is what you really need. The usage of UNICODE during the parsing of the command line is in my opinion mandatory if you want to have a general solution.

like image 31
Oleg Avatar answered Sep 17 '22 18:09

Oleg