the first two are easy to achieve:
- open file
- copy file handle to hStdOutput in STARTUPINFO struct 'si'
- add STARTF_USESTDHANDLES to si.dwFlags
- call CreateProcess with bInheritHandles TRUE and CREATE_NEW_CONSOLE in
dwCreationFlags
but the third not so -- obviously redirecting standard i/o handles is an
all-or-nothing thing and since i can't get the stderr handle of the console
which is created when i call CreateProcess i can't set the hStdError field
of the STARTUPINFO struct.
neither can i create a new console window and redirect the stderr output to
that because the parent process is a console-mode application.
any suggestions welcomed...
stephen/.
Why not? AFAIK CREATE_NEW_CONSOLE flag to CreateProcess is supposed
to work in your situation.
Jugoslav
___________
www.geocities.com/jdujic
sorry i should have been more clear -- i meant that i can't use the
Free/AllocConsole API or else i'll lose my app's existing console.
if i specify CREATE_NEW_CONSOLE i get a new console all right -- but it's
blank -- because to redirect the StdOut to a file i've had to use the
STARTF_USESTDHANDLES in the STARTUPINFO dwFlags field and i can't
assign anything to the StdError handle because the console window hasn't
been created yet and ... phew! ...
or am i missing something?
-stephen/.
Are you trying to get stderr of the sub-process to come back to the
console window of the original process?
If so, use GetStdHandle(STD_ERROR_HANDLE) and (probably)
DuplicateHandle() get an inheritable handle to stderr in the original
process. Put that in hStdError in STARTUPINFO when you call
CreateProcess().
Norm
thanks for the tip but no, i want the stderr output to appear in
the console window of the child process.
imagine you're running a Win32 console-mode app, one which outputs to stdout
and stderr, at a command prompt, and you redirect stdout to a file:
cmd> myapp.exe > output.txt
the stderr still appears in the command-prompt window.
that's the behaviour i want -- spawn the app using CreateProcess with
CREATE_NEW_CONSOLE, redirect the StdOut output to a file but have the
StdErr output still appear in the child process console window.
char *lpCommandLine = "myapp.exe";
char *lpFileName = "output.txt";
BOOL bInheritHandles;
DWORD dwCreationFlags;
HANDLE htdOutRedirectionFile;
STARTUPINFO si;
PROCESS_INFORMATION pi;
// Redirected output file
hStdOutRedirectionFile = CreateFile(lpFileName, ...);
// Startup-Information
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.dwFlags |= STARTF_USESTDHANDLES;
si.hStdOutput = hStdOutRedirectionFile;
// but what can i possibly set si.hStdError to here?
// si.hStdOutput = ???;
// 'Spawn' process
bInheritHandles = TRUE;
dwCreationFlags = CREATE_NEW_CONSOLE;
CreateProcess(NULL, // Application name
lpCommandLine, // Command line string
NULL, // Process security attributes
NULL, // Thread security attributes
bInheritHandles, // Handle inheritance flag
dwCreationFlags, // Creation flags
NULL, // New environment block
NULL, // Current directory name
&si, // STARTUPINFO
&pi); // PROCESS_INFORMATION
etc...
hope this is readable ;)
stephen/.
Write a small program that expects argv[1] to be the name of a file
(i.e. output.txt) and the remainder of the command line to be the name
of another executable (i.e. myapp.exe) and any arguments that it
requires.
This small program opens output.txt with an inheritable handle and then
uses CreateProcess() to run myapp.exe with stdout of myapp.exe
redirected to the handle of output.txt and stderr of myapp.exe
redirected to the console belonging to this small program.
Now, in your original application, you can use CreateProcess() with
CREATE_NEW_CONSOLE to run this small program with an appropriate command
line.
I haven't tried it but it looks like it ought to work.
Norm
Doh... what a chicken & egg situation indeed...
| > that's the behaviour i want -- spawn the app using CreateProcess with
| > CREATE_NEW_CONSOLE, redirect the StdOut output to a file but have the
| > StdErr output still appear in the child process console window.
| >
| \
| How about this:
<snip>
Another idea would be to modify the source of the 2nd application
so that it's essentially a WinMain app with console:
int WINAPI WinMain(hInstance,...
hOutHandle = GetStdHandle(STD_OUTPUT_HANDLE); // remember this...
AllocConsole(); // this will reset handles to new ones;
SetStdHandle(STD_OUTPUT_HANDLE, hOutHandle) // set this one back
alternatively, you could use console app instead, but which
would do a FreeConsole before the code above.
Jugoslav
___________
www.geocities.com/jdujic
...oh, I've just remembered that there's also DETACHED_PROCESS
flag for CreateProcess, which (by my reading at least) does not
create new console for the process at all.
Jugoslav
___________
www.geocities.com/jdujic
this is as much about solving this problem (i have a particular instance
for which this is a problem) as finding out whether or not this is a bug/
shortcoming in the Win32 API.
the solution i have just settled on -- which seems a little too obvious
to be the answer to my prayers, but it's a start -- albeit a kinda ugly
one -- is this:
assume that, like DOS, the _unredirected_ standard I/O handles to an
application (a console-mode one, anyway) are always the same -- a quick
test shows that StdOut appears to default to 7, and StdError to 11.
so the quik-fix (tm) is
si.hStdError = (HANDLE)11;
this works just fine.
whether or not i can rely on this value to remain constant is anyone's
guess.
thanks for your ideas,
stephen/.