Article View: borland.public.cppbuilder.nativeapi
Article #6934Console stays open after redirected CreateProcess.
From: Bob Gonder
Date: Thu, 24 Mar 2005 20:04
Date: Thu, 24 Mar 2005 20:04
158 lines
5743 bytes
5743 bytes
XP-Home sp2, BCB 5.5
Trying to get my Server app to execute a DOS app and redirect the
output to the Client.
This works, but later, when the Server closes, it's console stays
open. If the Client doesn't request this particular service before
closing, the console goes away just fine.
Task Manager Process entry for the program goes away like it should.
The Application tab still shows the program.
The Performance tab increases Handles, Threads, Processes for each
execution until the windows are manually closed.
Handles reduce with each closed window, but remain higher than
pre-execution. (Am I missing some Handle Closes?)
Eventually, I'd like to do away with the Server's console, but the
redirection doesn't seem to work at all without one.
So, Two Questions: (L and N in the truth table below)
1) Why does the console remain after program shutdown (and how to
close it).
2) Why doesn't redirection work without a Console (WithConsole==0)?
3) Am I missing some Handle Closes?
(I added > to every line to defeat word wrapping. The code contains no
'>', so you can do a global delete to clean them up.)
- - redirect.c
>#include "windows.h"
>#pragma hdrstop
>
>// Change these 3 settings
>#define WithConsole 1
>#define Run 1
>#define Redirect 1
>/*
> Redirect 0 Redirect 1
> Run1 Run0 Run1
> Cons1 L Ok L
> Cons0 Ok Ok N
>L == Console remains after termination.
>N == No "(Redirect)Data" Trace
>*/
>#if WithConsole
> DWORD TraceBytesWritten;
>#define Trace(x) WriteFile( stdout,x,lstrlen(x),&TraceBytesWritten,NULL);
>#else
>#define Trace(x) OutputDebugString(x);
>#endif
>
>HANDLE stdout,stdin;
>HANDLE MainThreadHandle; // handle to main() thread
>DWORD MainThreadID; // id to main() thread
>
>DWORD _stdcall run_program( char*command )
>{ DWORD ExitCode=0;
> STARTUPINFO si={0};
> PROCESS_INFORMATION pi={0};
>#if Redirect
> char buf[128];
> DWORD BytesRead;
> HANDLE hStdinRd, hStdinWr, hStdoutRd, hStdoutWr;
> SECURITY_ATTRIBUTES saAttr;
>
> saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
> saAttr.bInheritHandle = TRUE;
> saAttr.lpSecurityDescriptor = NULL;
> CreatePipe(&hStdoutRd, &hStdoutWr, &saAttr, 0);
> CreatePipe(&hStdinRd, &hStdinWr, &saAttr, 0);
> si.hStdInput = hStdinRd;
> si.hStdOutput = hStdoutWr;
> si.hStdError = hStdoutWr;
>#else
> si.hStdInput = stdin;
> si.hStdOutput = stdout;
> si.hStdError = stdout;
>#endif
> si.cb = sizeof(si);
> si.dwFlags = STARTF_USESTDHANDLES;
>
> if( CreateProcess( 0, command, 0, 0, TRUE, 0, 0, 0, &si, &pi) )
> {
> Trace("\n(Run)Accepted");
> WaitForSingleObject( pi.hProcess, INFINITE );
> GetExitCodeProcess( pi.hProcess, &ExitCode );
> Trace("\n(Run)Completed");
> CloseHandle( pi.hProcess );
> CloseHandle( pi.hThread );
> }else{
> ExitCode = GetLastError();
> Trace("\n(Run)Aborted");
> };
>#if Redirect
> CloseHandle( hStdoutWr );
> CloseHandle( hStdinWr );
> do{
> Trace("\n(Redirect)CheckingData\n");
> ReadFile( hStdoutRd, buf, sizeof(buf)-1, &BytesRead, NULL );
> if( BytesRead )
> { Trace("\n(Redirect)Data\n");
> buf[BytesRead] = 0;
>#if WithConsole
> OutputDebugString(buf);//verify debugstring works
>#endif
> Trace(buf);
> };
> }while( BytesRead );
> CloseHandle( hStdoutRd );
> CloseHandle( hStdinRd );
>#endif
> return ExitCode;
>}
>
>#pragma argsused
>unsigned long _stdcall smain(void*x) /* thread wrapper for main() */
>{
>#if Run
> run_program( "PKZIP.EXE bak.zip *.bak" );
>#else
> run_program( "PKZaP.EXE bak.zip *.bak" );
>#endif
> Trace("\n(Main)Completed");
> return 0;
>}
>
>#pragma argsused
>int _stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
>{ MSG msg = {0}; // message
>#if WithConsole
> AllocConsole();
>#endif
> stdin = GetStdHandle(STD_INPUT_HANDLE); /*Standard input handle*/
> stdout = GetStdHandle(STD_OUTPUT_HANDLE);
>
> if( 0!=(MainThreadHandle = CreateThread( NULL,0, smain, NULL,0, &MainThreadID)) )
> {
> Trace("\n(Win)BeginMessageLoop");
>
>// CreateWindow and Message loop replaced to simplify
> WaitForSingleObject( MainThreadHandle, INFINITE );
>
> Trace("\n(Win)EndMessageLoop");
> CloseHandle( MainThreadHandle );
> };
> Trace("\n(Win)Leaving WinMain");
>#if WithConsole
> FreeConsole(); // no difference
>#endif
> return msg.wParam; // Returns the value from PostQuitMessage
>}
- - Compilation switches
>CC = $(binpath)\bcc32 -6 -a1 -C -d -g50 -K -O2 -Oi -Os -Ov -Q -VI- -tW -vi -x- -P -M -v -c -I$(INCLUDEPATH) -L$(LIBPATH)
>TLINK = $(binpath)\ilink32 /aa/v/x/c/C/Gn/P-/Twe/L$(LIBPATH)
>#I can't remember where that /P- or /Twe came from? Removing them, no difference.
>$(TLINK) c0w32.obj+$(FILE).obj, $(FILE), , import32.lib+noeh32+cw32mt.lib
Technical Details
Message-ID:
<vi36411dhum1dho5li05dbbsj044qur13j@4ax.com>Path:
arc1-ca.pugleaf.net!g2news1.google.com!news1.google.com!news.maxwell.syr.edu!irazu.switch.ch!switch.ch!news.belwue.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mailShow Full Headers
Complete Article Headers
X-Google-Thread: 10cc67,3a2a64440564cd69,start X-Google-Attributes: gid10cc67,public X-Google-Language: ENGLISH,ASCII-7-bit From: Bob Gonder <notbg@notmindspring.invalid> Newsgroups: borland.public.cppbuilder.nativeapi Subject: Console stays open after redirected CreateProcess. Date: Thu, 24 Mar 2005 12:04:13 -0800 Organization: MindSpring Enterprises, Inc. Reply-To: notbg@notmindspring.invalid Message-ID: <vi36411dhum1dho5li05dbbsj044qur13j@4ax.com> X-Newsreader: Forte Agent 1.93/32.576 English (American) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit NNTP-Posting-Host: 67.77.146.183 X-Trace: newsgroups.borland.com 1111694652 67.77.146.183 (24 Mar 2005 12:04:12 -0800) Lines: 162 Path: arc1-ca.pugleaf.net!g2news1.google.com!news1.google.com!news.maxwell.syr.edu!irazu.switch.ch!switch.ch!news.belwue.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail