CreateProcess with arguments

This is a discussion on CreateProcess with arguments within the Windows Programming forums, part of the Platform Specific Boards category; Hello, I have problems using the 'CreateProcess' win32api function. I have been searching a bit here but I'm not able ...

CreateProcess with arguments

Hello, I have problems using the 'CreateProcess' win32api function. I have been searching a bit here but I'm not able to make it run.

The scenario: I have a very simple server program and I would like to enable it to work with php; I also have php5 (php-cgi.exe); I'm trying to call the php-cgi.exe to interpret the php files and dump the result on a temporary file in my server's temporary folder, but I need to know when the interpret have finishet the job. I have created a simple CreateProcess demo to test it (and to not post the whole code here) and that's it

The "C:\\PHP\\php-cgi.exe" is the path to the php interpret, the "C:\\Documents and Settings\\Aeiou\\SERVIDOR\\dirweb\\demo.php" is the path to the client request (ok, for that sample is a fixed request file), and the "C:\\Documents and Settings\\Aeiou\\SERVIDOR\\dirtmp\\out00.txt" will be the dumped result.

If I runt that code, instead of getting the output file, create it and dumping the result, it shows the result (or the errors if there's any) on the command prompt, so there's no output file. But if I work manually from the command prompt with files in the same folder as the php interpret it works well (obviously that isn't what I look for).

but the result is the same, it dumps the result to the command prompt and there's no output file. Finally I have also tryed to call the interpret with all the arguments (argument #0 = path to the interpret + arguments, argument#1 = null, etc...) but the result is an uppercase ERROR on the command line prompt.

From first glance, I'd be willing to bet that output redirection via ">" doesn't work as intended unless using it directly from the console window (or at the very least, in the case of trying to specifiy it in the lpCommandLine argument of CreateProcess).
According to STARTUPINFO, you can specify the STARTF_USESTDHANDLES flag in dwFlags to direct input/output/error to handles you supply. You could then try setting hStdOutput to a file you've opened through CreateFile (from your example, out00.txt).

If CreateProcess in general is just being stubborn, you could also try using ShellExecuteEx, however this has a similar argument structure to CreateProcess, so would probably have similar limitations.

A simple solution would be to put the entire command into a batch file (.bat, .cmd) and CreateProcess() on the batch file. You may have to use "start /wait" so that the batch file doesn't "return" early.

@nthony: I didn't realized about that point on the STARTUPINFO struct, I'll have to try that. And I have already thought using the ShellExecute, but I'm not sure on how to wait till the proc ends (on the Win32 API Manual Ref. says that the 'WaitForSingleObject' function only works for 'CreateProcess' and for 'CreateThread' -also others I think not related to that- ), so I can't use it with the ShellExecute.

Codeplug: I have been searching some information about the php arguments and the only I found is that std prompt redirection, so I thought that would work. About the idea on creating a batch file: I don't like at all, because the server serves in mulithreaded mode, so for each request I wuold have to create a new temporary batch, execute it using another temporary result file and finally delete both; since I have the method to create the temporary result file won't be difficult to create anotgher for the bat, but I was thinking that php can have some 'auto create result file'. For the own I/O redirection I'll take a look.

Hello Codeplug, thank's for that last apport. I already know a little the usage of batch files but thank's for the code sample.

I have tested with the stdhandles on the startup info, and also with the batch file, but I think that I should have a misconfiguration on the php module because the output file is created (well, in the first case I create it in write_shared mode), but after the interpretation the size is 0 bytes (the interpret doesn't dump any data to the file, nor to the command prompt).

The output size at the end is 0 bytes, there's no errors from the interpret (I have veryfied that the php file is at the folder specifyed, so synthax-errors on the path won't be the problem -I think- ). I have also tryed to setup the stdinput param of the STARTUPINFO struct to a handle on the request file (opened with 'CreateFile' for read|write), but the result is the same.

And for the method of batch files, I have the same php input file, and the bat looks like the last Codeplug post

Hey hello Codeplug: yes, the 'start ""/wait' is the trouble, but the '\wait' is also a solution for me because I will create the bat process wint 'CreateProcess' and I need to know when have been finished ('WaitForSingleObject'), so the '/wait' will ensure that the bat proc won't be finished before the child php-interpret's process.

For the own I/O redirection I have seen it on your first post, but on getting the stdout of my proc since the server program runs as multithreaded services, I'm afraid that some data could be mixed in some way. Althought I will take a look because it seems that can be the only way to solve that problem.

1-. I think that php-cgi isn't a regular console application, but when I provide a file to interpret it works as it be a console app. However I will tray that, and I'll post the results.

2-. I have read the article and compiled the sample code, and I already have thought that the 'hStdout' since is HANDLE variable will work exactly as the HANDLE vars on the STARTUPINFO struct used to call 'CreateProcess' where I can (or I should be able to) (better, I would like to be able to) redirect the output to my own file handler.

And still not working; why is so difficult??? Maybe tomorrow some divine inspiration will come to me...

I probably should have pointed this out before, but I figured it would have been evident from the MSDN page: the Standard Handles must be inheritable and bInheritHandles must be set to TRUE in CreateProcess.
So you must specify bInheritHandle as TRUE in the SECURITY_ATTRIBUTES struct for CreateFile, as well you must also specify it TRUE for CreateProcess.

Originally Posted by STARTUPINFO

If this flag is specified when calling one of the process creation functions, the handles must be inheritable and the function's bInheritHandles parameter must be set to TRUE. For more information, see Handle Inheritance.

Codeplug: using the 'call' instead the 'start /wait' have been solving the problem for the use of a bat file. That will be the default bat file for all the php interpret calls

Code:

@echo off
set php=%1
set font=%2
set out=%3
call %php% -f %font% >%out%

and the CreateProcess (without the inheritance changes) will be a simple

Code:

...
//here the structures setup are the same as on my last 3rd post
//because the problem was on the bat file
CreateProcess("mybatforphp.bat","path_to_php.exe path_to_font.php path_to_tmpoutput.html",NULL,NULL,0,0,NULL,NULL,&si,
&pi);
WaitForSingleObject(pi.hProcess,INFINITE);
//the bat have finished, so here I can access the output
...

So with that I can launch the bat file with some args that will call the php interpret, the bat will wait till the php interpret ends its job, and I'm able to wait till the bat ends its own.

@nthony: sure that the explanations on win32api man.ref. are right, but sometimes people reads between lines to speed up the job (and to obtain more errors and problems, like my case). I have made the corrections you point and now that method also works well:

anonytmouse: I'll have 'stolen' a trick from your code on the link you posted, the 'CREATE_NO_WINDOW' flag. What's that? Another non-documented win value? It doesn't appears on my copy of Win32PI Man.Ref, but it works.

If you don't mind, I'll use the CreateProcess with the inheritance flags on because in that way only 2 programs will run (the server and the php interpret, in the other case will be running the server, the bat and the php).