Click here to Skip to main content
11,412,516 members (74,216 online)
Click here to Skip to main content

Redirecting an arbitrary Console's Input/Output

, 27 Nov 2003
Rate this:
Please Sign up or sign in to vote.
Redirecting an arbitrary console's input/output in a simple, graceful way

Sample Image - redir.gif


To redirect the input/output of a console application is interesting and useful. You can display the child's output in a window (just like Visual Studio's output window), or search some keywords in the output string to determine if the child process has completed its work successfully. An old, 'ugly' DOS program could become an useful component of your fancy Win32 GUI program.

My idea is to develop a simple, easy to use redirector class which can redirect an arbitrary console, and won't be affected by the behavior of the child process.


The technique of redirecting the input/output of a console process is very sample: The CreateProcess() API through the STARTUPINFO structure enables us to redirect the standard handles of a child console based process. So we can set these handles to either a pipe handle, file handle, or any handle that we can read and write. The detail of this technique has been described clearly in MSDN: HOWTO: Spawn Console Processes with Redirected Standard Handles.

However, MSDN's sample code has two big problem. First, it assumes the child process will send output at first, then wait for input, then flush the output buffer and exit. If the child process doesn't behave like that, the parent process will be hung up. The reason of this is the ReadFile() function remains blocked untill the child process sends some output, or exits.

Second, It has problem to redirect a 16-bit console (including console based MS-DOS applications.) On Windows 9x, ReadFile remains blocked even after the child process has terminated; On Windows NT/XP, ReadFile always returns FALSE with error code set to ERROR_BROKEN_PIPE if the child process is a DOS application.

Solving the block problem of ReadFile

To prevent the parent process from being blocked by ReadFile, we can simply pass a file handle as stdout to the child process, then monitor this file. A more simple way is to call PeekNamedPipe() function before calling ReadFile(). The PeekNamedPipe function checks information about data in the pipe, then returns immediately. If there's no data available in the pipe, don't call ReadFile.

By calling PeekNamedPipe before ReadFile, we also solve the block problem of redirecting a 16-bit console on Windows 9x.

The class CRedirector creates pipes and launchs the child process at first. then creates a listener thread to monitor the output of the child process. This is the main loop of the listener thread:

    for (;;)
        // redirect stdout till there's no more data.
        nRet = pRedir->RedirectStdout();
        if (nRet <= 0)

        // check if the child process has terminated.
        DWORD dwRc = ::WaitForMultipleObjects(
            2, aHandles, FALSE, pRedir->m_dwWaitTime);
        if (WAIT_OBJECT_0 == dwRc)      // the child process ended
        if (WAIT_OBJECT_0+1 == dwRc)    // m_hEvtStop was signalled, exit

This is the main loop of the RedirectStdout() function:

    for (;;)
        DWORD dwAvail = 0;
        if (!::PeekNamedPipe(m_hStdoutRead, NULL, 0, NULL,
            &dwAvail, NULL))    // error, the child process might ended

        if (!dwAvail)           // no data available, return
            return 1;

        char szOutput[256];
        DWORD dwRead = 0;
        if (!::ReadFile(m_hStdoutRead, szOutput, min(255, dwAvail),
            &dwRead, NULL) || !dwRead)  
                 // error, the child process might ended

        szOutput[dwRead] = 0;
        WriteStdOut(szOutput);          // display the output

WriteStdOut is a virtual member function. It does nothing in CRedirector class. However it can be overrided to achieve our specific target, like I did in the demo project:

    int nSize = m_pWnd->GetWindowTextLength();  
             // m_pWnd points to a multiline Edit control
    m_pWnd->SetSel(nSize, nSize);
           // add the message to the end of Edit control

To redirect DOS console based applications on NT/2000/XP

MSDN's solution is to launch an intermediate Win32 Console application as a stub process between the Win32 parent and the 16-bit console based child. In fact the DOS prompt program (on NT/XP it's cmd.exe, on 9x it's is a natural stub process we just need. We can test this in RedirDemo.exe:

  1. Input 'cmd.exe' in Command Editbox, then press Run button.
  2. Input the name of the 16-bit console based application (dosapp.exe for example) in the Input Editbox, then press Input button. Now we can see the output of the 16-bit consol.
  3. Input 'exit' in the Input Editbox, then press Input button to terminate cmd.exe

Apparently this is not a good solution because it's too complicated. A more effective way is to use a batch file as the stub. Edit stub.bat file like this:

%1 %2 %3 %4 %5 %6 %7 %8 %9

Then run a command like 'stub.bat dosapp.exe', then the 16-bit DOS console application runs OK.


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Web Developer
Canada Canada
Nick Adams is one of my favorite figures in Hemingway's stories. I use it because Jeff Lee has been occupied on Codeproject.

Comments and Discussions

QuestionHow do I use the Redirection Demo tool? Pin
Mike Dorl at 26-Feb-15 8:46
memberMike Dorl26-Feb-15 8:46 
QuestionWhich License? Pin
tngraf001 at 26-Nov-14 3:55
membertngraf00126-Nov-14 3:55 
QuestionCan this be done in QT? Pin
Shaunak De at 13-Aug-13 20:43
memberShaunak De13-Aug-13 20:43 
BugUnicode Character Set Pin
prashu100 at 30-Aug-12 5:04
memberprashu10030-Aug-12 5:04 
QuestionAbout running a FTP console app, just like telnet Pin
LionKun at 11-Dec-11 3:15
memberLionKun11-Dec-11 3:15 
GeneralMy vote of 4 Pin
Normand M. Blais at 3-Oct-10 6:03
memberNormand M. Blais3-Oct-10 6:03 
QuestionIt is not working on windows 2008 R2 Pin
manas.thombare at 8-Jul-10 7:25
membermanas.thombare8-Jul-10 7:25 
GeneralBe aware of casting LPCTSTR to LPTSTR Pin
EmoBemo at 30-Nov-09 7:14
memberEmoBemo30-Nov-09 7:14 
GeneralThanks! Pin
Kyudos at 17-Sep-09 18:24
memberKyudos17-Sep-09 18:24 
GeneralSuperb execution... but have a simple question... Pin
Hurty at 9-Jul-09 23:52
memberHurty9-Jul-09 23:52 
GeneralWriteStdError shouldn't be called with _T Pin
sashoalm at 17-Apr-09 23:55
membersashoalm17-Apr-09 23:55 
Generaltelnet.exe Pin
suiram40 at 24-Feb-09 19:01
membersuiram4024-Feb-09 19:01 
GeneralCaptureConsole.DLL - A universal Console Output Redirector for all Compilers Pin
Elmue at 3-Feb-09 7:02
memberElmue3-Feb-09 7:02 
GeneralStrange problem Pin
Mr. S at 27-Nov-08 1:30
memberMr. S27-Nov-08 1:30 
GeneralTelnet.exe Pin
tptshepo at 11-Nov-08 20:55
membertptshepo11-Nov-08 20:55 
Questionhow to send a CTRL+C??? Pin
Motorcure at 17-Sep-08 0:08
memberMotorcure17-Sep-08 0:08 
AnswerRe: how to send a CTRL+C??? Pin
varandas79 at 18-Mar-11 7:02
membervarandas7918-Mar-11 7:02 
QuestionHow to you know when the process has ended? Pin
mimosa at 21-Apr-08 14:28
membermimosa21-Apr-08 14:28 
GeneralAbout Redirecting Debug IO Pin
yonken at 6-Apr-08 1:26
memberyonken6-Apr-08 1:26 
QuestionHow to change the bounds of bytes to output data at a time. Pin
chol921 at 12-Nov-07 23:19
memberchol92112-Nov-07 23:19 port Pin
neolode at 16-Sep-07 7:38
memberneolode16-Sep-07 7:38 
GeneralOverlapped structure Pin
charian0920 at 3-May-07 18:28
membercharian09203-May-07 18:28 
QuestionAlso works for DLLs? Pin
roel hermans at 3-May-07 2:28
memberroel hermans3-May-07 2:28 
QuestionWhat about advanced key events? Pin
torch#2 at 7-Mar-07 23:49
membertorch#27-Mar-07 23:49 
QuestionAdapting To Windows Powershell? Pin
Robert T. at 25-Oct-06 10:33
memberRobert T.25-Oct-06 10:33 
AnswerRe: Adapting To Windows Powershell? Pin
Anne Jan Beeks at 31-Jan-07 4:22
memberAnne Jan Beeks31-Jan-07 4:22 
GeneralRe: Adapting To Windows Powershell? Pin
Robert T. at 26-Mar-07 7:07
memberRobert T.26-Mar-07 7:07 
GeneralRe: Adapting To Windows Powershell? Pin
Anne Jan Beeks at 26-Mar-07 7:32
memberAnne Jan Beeks26-Mar-07 7:32 
QuestionHow to avoid using fflush(); ? Pin at 1-Oct-06 9:10
memberq.sa1-Oct-06 9:10 
QuestionAsking for help, Unexpected behavior with my client app Pin
gemex at 9-Aug-06 23:18
membergemex9-Aug-06 23:18 
GeneralCalling CRedirector::Close() in output thread problem ! Pin
Reivax72 at 14-Jun-06 1:26
memberReivax7214-Jun-06 1:26 
GeneralPlease Help me VB Pin
WolverineSoft at 2-May-06 14:15
memberWolverineSoft2-May-06 14:15 
General::SetConsoleCtrlHandler(CRedirector::CtrlHandler, TRUE); Pin
Tcpip2005 at 25-Apr-06 23:06
memberTcpip200525-Apr-06 23:06 
GeneralRe: ::SetConsoleCtrlHandler(CRedirector::CtrlHandler, TRUE); Pin
Motorcure at 17-Sep-08 16:33
memberMotorcure17-Sep-08 16:33 
QuestionHow can i flush the clild's data? Pin
Galterian at 20-Feb-06 2:34
memberGalterian20-Feb-06 2:34 
QuestionWhy the telnet doesn't work with it? Pin
iamtony at 3-May-05 17:27
memberiamtony3-May-05 17:27 
AnswerRe: Why the telnet doesn't work with it? Pin
nickadams at 4-May-05 5:01
membernickadams4-May-05 5:01 
GeneralRe: Why the telnet doesn't work with it? Pin
osirisgothra at 6-Sep-07 8:07
memberosirisgothra6-Sep-07 8:07 
GeneralRedirecting Cygwin Console Pin
sars at 14-Mar-05 15:35
membersars14-Mar-05 15:35 
Generalprintf problem is not solved.... Pin
Monk_ at 10-Dec-04 2:18
memberMonk_10-Dec-04 2:18 
GeneralRe: printf problem is not solved.... Pin
Anonymous at 10-Dec-04 12:31
sussAnonymous10-Dec-04 12:31 
GeneralNot all stdout or stderr is printed Pin
jarrusin at 19-Nov-04 9:16
memberjarrusin19-Nov-04 9:16 
Generalredirecting output of console application consisting of several threads Pin
Luft Waffe at 12-Nov-04 4:13
memberLuft Waffe12-Nov-04 4:13 
GeneralRe: redirecting output of console application consisting of several threads Pin
nickadams at 17-Nov-04 17:28
membernickadams17-Nov-04 17:28 
QuestionHow can i stop the running Process ? Pin
Sick@work at 28-Jul-04 3:02
memberSick@work28-Jul-04 3:02 
AnswerRe: How can i stop the running Process ? Pin
nickadams at 29-Jul-04 5:10
membernickadams29-Jul-04 5:10 
GeneralRe: How can i stop the running Process ? Pin
Sick@work at 4-Aug-04 1:12
memberSick@work4-Aug-04 1:12 
GeneralRe: How can i stop the running Process ? Pin
nickadams at 5-Aug-04 4:16
membernickadams5-Aug-04 4:16 
GeneralRe: How can i stop the running Process ? Pin
Michael A. Rusakov at 10-Jul-07 4:30
memberMichael A. Rusakov10-Jul-07 4:30 
GeneralRe: How can i stop the running Process ? Pin
vikijain at 8-Nov-04 5:29
membervikijain8-Nov-04 5:29 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150427.1 | Last Updated 28 Nov 2003
Article Copyright 2003 by nickadams
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid