Background Info: Windows 7, Visual C++ 2010 Express
Problem: CreateProcess() keeps returning with 'Invalid command line argument'
Explanation: I'm writing a piece of code that calls external programs using the Windows API's CreateProcess. I've gotten the call to work with one external program so far:
if( !CreateProcess( "C:\\Temp\\convert.exe",
t_str, // Arguments
...
}
//where t_str is " C:\\img1.jpeg C:\\img1.pgm" (ImageMagick if you're wondering).
This works perfectly even with the amount of data-mangling I did to push everything into the Windows strings and pointers. So I copied all of the mangling for CreateProcess() for another call to a different external program:
if( !CreateProcess( "C:\\Temp\\sift.exe",
t_str2, // Arguments
...
}
//where t_str2 is ` < C:\\img1.pgm > C:\\img1.key`
Basically, something very similar, but with all the variable names changed (since I have these two calls running serial). And this is where the problem is; this doesn't run, and, instead, prints out "Invalid command line argument: < C:\img1.pgm". Of course, this command works fine in the command prompt, but not in my code.
I switched t_str2 to something else a little less complicated(since I know how sift.exe works) and I get the same result. Same thing happens when I run just sift and not convert.
Question: What could be causing this problem? What could I do to further debug this problem? Any suggestions on alternatives to the methods I'm using? Any help is appreciated. I can provide further code, but It's pretty straight forward, and not much could go wrong with it.
CreateProcess
has some annoying gotchas, and the older answers across Stack Exchange can make that process somewhat troublesome if you're not also referencing the official documentation.CreateProcess
is for the most part optional, which is really weird for a first parameter. If you don't want to specify it, useNULL
, otherwise you should read the very specific documentation on how to use parameter 1 when not setting it toNULL
.NULL
, the application needs to be the first part of parameter 2.Thanks again to Remy for clearing up the weird behavior on my initial answer.
This code sample only requires a basic VC++ compiler on Windows and the ability to make and store a file on the Desktop that will be opened by Notepad.
If that's not practical, feel free to use
%temp%
or some other location for placing the test file. The app will run until you close notepad.exe. This also handles getting and returning the exit code. If you don't want it to run indefinitely until exit, you'll need to update theWaitForSingleObject
line.In the second example you are trying to use standard input and out redirections, which are notations of the command line application. But they are not valid program arguments. If you want use redirection you should open pipes and manualy read and write from/to input/output files. Here you can find an example how to implement pthe process creation with input/output redirections.
You cannot use command-line redirection operators with
CreateProcess()
directly. You have to spawn an instance of cmd.exe and pass the operators to it instead, eg:Where
t_str2
is"/C C:\\Temp\\sift.exe < C:\\img1.pgm > C:\\img1.key"
. The actual path to cmd.exe can be determined by reading the%COMSPEC%
environment variable.