Friday, July 10, 2009

C/C++ CreateProcess command line param problem

Back to some tech stuff, a simple task yesterday made me much headaches. I needed to run pdftk.exe from our program. I figured out the params and all worked as a dream. Let's implement it:
CreateProcess("pdftk.exe", "a.pdf b.pdf cat output c.pdf dont_ask", ...)

And it did not work. I failed to get any error, any output. Then I tried with cmd:

CreateProcess("cmd.exe", "/C pdftk.exe a.pdf b.pdf cat output c.pdf dont_ask", ...)

And it worked, but why? And I don't want the cmd.exe to be involved. I saw an example where program name was null:

CreateProcess(NULL, "pdftk.exe a.pdf b.pdf cat output c.pdf dont_ask", ...)

And it worked, ok, we got rid of cmd.exe.
WTF? The program name is null and the params, wait, command line!

The flexibility of the CreateProcess() function (and a possible point of confusion) arises when you pass a valid string pointer to both the ApplicationName and CommandLine parameters. This allows you to specify the application to be executed as well as the complete command line that is passed to the application. One might assume that the command line passed to the created application is a composite of the ApplicationName and CommandLine parameters, but this is not the case. As a result, a process created by CreateProcess can receive a value other than its .exe name as its "argv[0]" parameter. The following is an example of a call to CreateProcess that produces this "abnormal" behavior:
   CreateProcess( "c:\\MyApp.exe", "Param1 Param2 Param3", ...)
MyApp's arguments will be as follow:
  argv[0] == "Param1"
argv[1] == "Param2"
argv[2] == "Param3"
Read more about it here. Hope it will save you some time :)

No comments: