system() and CreateProcess() / CreateProcessW()
Asked Answered
M

3

6

I want to execute a TEST.exe in a C program. While I use

system( "TEST.exe <input-file> output-file" );

I can get what I expected.

But CreateProcessW() didn't work properly when I use the following code (see How do I run an external program?):

if (CreateProcessW(const_cast<LPCWSTR>(FullPathToExe.c_str()), 
    pwszParam, 0, 0, false, 
    CREATE_DEFAULT_ERROR_MODE, 0, 0, 
    &siStartupInfo, &piProcessInfo) != false) 
{ 
    /* Watch the process. */ 
    dwExitCode = WaitForSingleObject(piProcessInfo.hProcess,  (SecondsToWait * 1000)); 
    iReturnVal = GetLastError(); 
} 
else 
{ 
    /* CreateProcess failed */ 
    iReturnVal = GetLastError(); 
} 

where

FullPathToExe="TEST.exe", pwszParam="TEST.exe <input-file> output-file".

And WaitForSingleObject() returns 258, GetLastError() returns 1813 ("The specified resource type cannot be found in the image file.").

Also, The above CreateProcessW() code works fine when I run my own HelloProcess.exe (print hello, and sleep some seconds determined by the following number, then exit.) with

FullPathToExe="HelloProcess.exe", pwszParam="HelloProcess.exe 10".

Any ideas? Thanks for any hints!

Medina answered 2/4, 2012 at 3:57 Comment(3)
Is FullPathToExe a string or a wstring?Ecclesiastic
It's a wstring. I think the types of variables are OK, since the code runs well with my own *.exe. I wonder if there is some problem with the "<"/">" in the parameters?Medina
Title should be changed to “Input/output redirection: system() vs. CreateProcess()” but I’m not allowed to edit it. Also spacing is inconsequential – and hence misleading – in <input-file> output-file. Characters <> are prefixes but OP’s spacing implies they are parentheses. Spacing that wouldn’t be misleading: <output-file >input-file.Fourthly
M
6

system actually spawns a cmd instance in which your command is run:

The system function passes command to the command interpreter, which executes the string as an operating-system command. system refers to the COMSPEC and PATH environment variables that locate the command-interpreter file (the file named CMD.EXE in Windows NT). If command is NULL, the function simply checks to see whether the command interpreter exists.
Documentation of system

This is why redirection operators such as < and > work. This is not the case for CreateProcess which really just spawns a process instead of a shell that executes another process. Since the redirection operators are a feature of the shell and not the OS you'd have to do input and output to the process manually.

Mastersinger answered 2/4, 2012 at 8:5 Comment(1)
Thanks so much for your explanation. And I find the solution to my problem now, hooray!!Medina
M
3

I do what CreateProcess and command line arguments tells me to do, and fix the problem! Thank you guys for your attention!

For your convenience, here is the quotation of the answer:

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:

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

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.

Medina answered 2/4, 2012 at 12:11 Comment(0)
D
0

WaitForSingleObject() returns a wait result, and not the exit code. https://msdn.microsoft.com/en-us/library/windows/desktop/ms687032(v=vs.85).aspx

258 is a WAIT_TIMEOUT. You should retry on this error code until you get the return value of 0 (WAIT_OBJECT_0), or some other error.

After this, use GetExitCodeProcess https://msdn.microsoft.com/en-us/library/windows/desktop/ms683189(v=vs.85).aspx to get the exit code of the process.

Derron answered 14/1, 2016 at 1:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.