CreateProcess and command line arguments

Background information: Windows 7, Visual C ++ 2010 Express

Problem: CreateProcess () continues to return using "Invalid command line argument"

Explanation: I am writing a piece of code that calls external programs using the Windows API CreateProcess. I got a call to work with one external program:

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 great even with the amount of data processing that I did to insert everything into Windows strings and pointers. Therefore, I copied all the mechanisms for CreateProcess () to another call to another external program:

  if( !CreateProcess( "C:\\Temp\\sift.exe", t_str2, // Arguments ... } //where t_str2 is ` < C:\\img1.pgm > C:\\img1.key` 

In principle, something very similar, but with the change of all variable names (since I have these two calls performed in series). And here is the problem; it does not start and instead displays "Invalid command line argument: <C: \ img1.pgm". Of course, this command works fine on the command line, 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. The same thing happens when I run just sifting and not converting.

Question: What could be causing this problem? What can I do to further debug this problem? Any suggestions on alternatives to the methods I use? Any help is appreciated. I can provide additional code, but it is pretty straightforward, and little can go wrong.

+4
source share
3 answers

You cannot directly use command line redirection operators with CreateProcess() . You must create an instance of cmd.exe and pass operators instead, for example:

 CreateProcess( "C:\\windows\\system32\\cmd.exe", t_str2, ...)) 

Where t_str2 is "/CC:\\Temp\\sift.exe < C:\\img1.pgm > C:\\img1.key" . The actual path to cmd.exe can be determined by reading the %COMSPEC% environment variable.

+9
source

In the second example, you are trying to use standard input and output redirects, which are notation for a command line application. But they are not valid program arguments. If you want to use redirection, you must open the channels and manually read and write from / to the I / O files. Here you can find an example of how to implement the process of creating a process with I / O redirection.

+4
source

CreateProcess has some annoying errors, and older responses through Stack Exchange may make this process somewhat difficult if you are not also referring to the official documentation.

  • Parameter 1 for CreateProcess is mostly optional, which is really strange for the first parameter. If you do not want to specify it, use NULL , otherwise you should read the specific documentation on how to use parameter 1 when not setting it to NULL .
  • If parameter 1 is NULL , the application must be the first part of parameter 2.

Thanks again to Remy for finding out the strange behavior of my original answer.


This code sample only requires the basic VC ++ compiler on Windows and the ability to create and store a file on the desktop that Notepad will open.

If this is not practical, feel free to use %temp% or another location to place the test file. The application will start until the notepad.exe file is closed. It also allows you to receive and return an exit code. If you do not want it to run indefinitely before exiting, you need to update the WaitForSingleObject line.

 #include <Windows.h> int main() { STARTUPINFOA startup_info = { 0 }; LPSTARTUPINFOA p_startup_info = &startup_info; PROCESS_INFORMATION proc_info = { 0 }; LPPROCESS_INFORMATION p_proc_info = &proc_info; char command_line[] = "C:\\Windows\\System32\\cmd.exe /C notepad.exe \"%USERPROFILE%\\Desktop\\test.txt\""; bool process_created = CreateProcess( NULL, command_line, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, p_startup_info, p_proc_info ); if (!process_created) { return -3; } DWORD process_exit; WaitForSingleObject(proc_info.hThread, INFINITE); GetExitCodeProcess(p_proc_info->hProcess, &process_exit); return (int)process_exit; } 
0
source

Source: https://habr.com/ru/post/1388199/


All Articles