Click here to Skip to main content
11,930,069 members (42,985 online)
Click here to Skip to main content
Add your own
alternative version


62 bookmarked

Controlling console applications

, 4 Feb 2002 Ms-PL
Rate this:
Please Sign up or sign in to vote.
Run console applications and controll/use their input/output streams
<!-- Download Links --> <!-- Add the rest of your HTML here -->

Console windows and application output

During a "simple" project I discovered the tedious task of capturing the output of a console window into a control of the application. The additional difficulty was to hide the console window, thus hiding the application.

As it was to be expected, things were not as easy as redirecting output into a file and reading that file back in.

So I started creating a wrapper class for this task and it proved harder than it seemed at first. The provided sample in the MSDN did not mention the most important things and leaves more questions then it solves.

Searching around on various code sites shed some more light on the topic. Finally I could assemble a working solution. (Although there are some minor wishes left)

The CSpawn Class

This class has a pretty simple interface. A constructor, an execute function, an output function and finally a test to see if it is still active. The execute function and the output function are available in various flavours.

For the feedback you must derive a class from CSpawnConsumer and overload the Consume() function.

Usually it looks like this:

class CSpawnConsumer1 : public CSpawnConsumer
    explicit CSpawnConsumer1(CMyEdit* pEdit)
                                   : m_pEdit(pEdit){}
    void Consume(TCHAR* p, DWORD dw)

    CMyEdit* m_pEdit;

This class is called from the thread reading the output of the console window.

You can use the CSpawn class in two ways:

  1. Using the constructor method CSpawn::CSpawn(CString& exe, CSpawnConsumer* sc)
  2. Or creating a CSpawn variable and calling Execute(CString& exe, CSpawnConsumer* sc)

The default implementation will spawn the executable by resolving the ComSpec environment variable (normally CMD.EXE or COMMAND.EXE) and passing parameters to the given application.

You can provide user input to a running application by calling SendInput().

The Sample

The included sample project shows a simple edit control where any text entered is passed to the standard command interpreter and returns the results into the same edit control.

It shows how to interface with the CSpawn class in the most common way.


CSpawn was tested under Windows 2000 and Windows XP in Unicode and MBCS (both included in demo project) using Visual C++ 6.0 SP5 and MFC 6. Its not tested with .NET and MFC 7.

Revision History

19 Jun 2002 - Initial Revision


This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)


About the Author

No Biography provided

You may also be interested in...

Comments and Discussions

GeneralCaptureConsole.DLL - A universal Console Output Redirector for all Compilers Pin
Elmue3-Feb-09 7:10
memberElmue3-Feb-09 7:10 
GeneralLinewise reading data Pin
smzhaq26-Sep-07 23:24
membersmzhaq26-Sep-07 23:24 
QuestionHow to terminate early Pin
acjohnson557-Jul-06 10:25
memberacjohnson557-Jul-06 10:25 
QuestionError storing m_hSaveStdout ? Pin
John P. Curtis25-Feb-06 19:56
memberJohn P. Curtis25-Feb-06 19:56 
AnswerRe: Error storing m_hSaveStdout ? Pin
SaurweinAndreas26-Feb-06 5:20
memberSaurweinAndreas26-Feb-06 5:20 
GeneralI fixed a bug Pin
Junho Ryu27-Sep-05 3:17
memberJunho Ryu27-Sep-05 3:17 
I have found a bug which can be duplicated when the child process has a delay between its stdout or stderr.

When there is a delay, the code checks whether the child process is still active by CSpawn::TestProcess. Because the function checks return value of GetExitCodeProcess instead of lpExitCode, CSpawn::ReadPipeThreadProc returns whether the child process is still running or not. Many people told about this before.

However, there was another problem.
Though the child process is already terminated, ReadFile does not return with the error code ERROR_BROKEN_PIPE. The reason is that the parent process also has both sides of handles of the pipes.

To fix the bug, close child side handles of pipes immediately after creating the child process. By doing it, we don't have to call PeekNamedPipe and GetExitCodeProcess. ReadFile will return an error. This is what Q190351[^] is doing.

And I think WaitForSingleObject (line 183) is unnecessary.

This is my spawn.cpp.[^]
GeneralRe: I fixed a bug Pin
acjohnson557-Jul-06 10:22
memberacjohnson557-Jul-06 10:22 
GeneralRe: I fixed a bug Pin
joeasnake21-Nov-07 16:32
memberjoeasnake21-Nov-07 16:32 
QuestionRe: I fixed a bug Pin
rl7477-May-08 6:46
memberrl7477-May-08 6:46 
GeneralInvalid Handle exception when creating several CSpawn classes Pin
johnpsquared1-Aug-04 14:26
memberjohnpsquared1-Aug-04 14:26 
Questionmultiline output? Pin
mikemurphy28-Feb-04 11:39
membermikemurphy28-Feb-04 11:39 
AnswerRe: multiline output? Pin
johnpsquared1-Aug-04 14:33
memberjohnpsquared1-Aug-04 14:33 
Questionhow to get all stdout during batch command mode Pin
Anonymous18-Dec-03 11:24
sussAnonymous18-Dec-03 11:24 
GeneralVC++ Newbie Help Pin
messy17-Oct-03 13:05
membermessy17-Oct-03 13:05 
GeneralSmall bug fix Pin
mschoneman23-Sep-03 15:13
membermschoneman23-Sep-03 15:13 
GeneralInvoking &quot;.cmd&quot; files Pin
dshah13-Jun-03 4:41
memberdshah13-Jun-03 4:41 
GeneralbRet = GetExitCodeProcess always true Pin
donaldw25-Apr-03 13:36
memberdonaldw25-Apr-03 13:36 
GeneralGetting stdout immediately Pin
Milhouse1006-Mar-03 1:49
memberMilhouse1006-Mar-03 1:49 
GeneralRe: Getting stdout immediately Pin
Andreas Saurwein6-Mar-03 2:19
memberAndreas Saurwein6-Mar-03 2:19 
GeneralRe: Getting stdout immediately Pin
Anonymous17-Mar-03 11:35
sussAnonymous17-Mar-03 11:35 
GeneralSendInput Question Pin
6R15U29-Sep-02 0:47
suss6R15U29-Sep-02 0:47 
GeneralRe: SendInput Question Pin
Andreas Saurwein4-Oct-02 1:24
memberAndreas Saurwein4-Oct-02 1:24 
GeneralHelp! with CSpawn class... Pin
johnpsquared1-Aug-04 14:29
memberjohnpsquared1-Aug-04 14:29 
GeneralQuestion when using with processes that spawn other processes Pin
Jim Crafton18-Sep-02 10:40
memberJim Crafton18-Sep-02 10:40 
GeneralRe: Question when using with processes that spawn other processes Pin
Andreas Saurwein23-Sep-02 2:06
memberAndreas Saurwein23-Sep-02 2:06 
Generalnon-starter for win9x/ME Pin
umeca7416-Sep-02 11:46
sussumeca7416-Sep-02 11:46 
GeneralRe: non-starter for win9x/ME Pin
Andreas Saurwein23-Sep-02 2:08
memberAndreas Saurwein23-Sep-02 2:08 
GeneralRedirecting existing process IO Pin
Anonymous22-Aug-02 5:15
memberAnonymous22-Aug-02 5:15 
GeneralRe: Redirecting existing process IO Pin
Andreas Saurwein26-Aug-02 2:02
sussAndreas Saurwein26-Aug-02 2:02 
GeneralWrong function! Pin
Nguyen Binh6-Aug-02 0:44
memberNguyen Binh6-Aug-02 0:44 
GeneralRe: Wrong function! Pin
Andreas Saurwein6-Aug-02 3:22
memberAndreas Saurwein6-Aug-02 3:22 
GeneralRe: Wrong function! Pin
Jim Crafton22-Aug-02 9:25
memberJim Crafton22-Aug-02 9:25 
General4k limitation Pin
Bed / Placid18-Jun-02 6:23
memberBed / Placid18-Jun-02 6:23 
GeneralRe: 4k limitation Pin
Andreas Saurwein18-Jun-02 6:55
memberAndreas Saurwein18-Jun-02 6:55 
Generalillegal memory access in Release config (Non-Unicode). Pin
Blade[DMS]4-Mar-02 7:54
memberBlade[DMS]4-Mar-02 7:54 
GeneralRe: illegal memory access in Release config (Non-Unicode). Pin
Andreas Saurwein4-Mar-02 13:01
memberAndreas Saurwein4-Mar-02 13:01 
GeneralRe: illegal memory access in Release config (Non-Unicode). Pin
Blade[DMS]5-Mar-02 0:08
memberBlade[DMS]5-Mar-02 0:08 
GeneralVerry cool Pin
Jim Crafton8-Feb-02 9:44
memberJim Crafton8-Feb-02 9:44 
Generaldirecting cout/stdout to window Pin
N Singh6-Feb-02 13:00
memberN Singh6-Feb-02 13:00 
GeneralRe: directing cout/stdout to window Pin
Andreas Saurwein6-Feb-02 13:10
memberAndreas Saurwein6-Feb-02 13:10 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    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
Web04 | 2.8.151126.1 | Last Updated 5 Feb 2002
Article Copyright 2002 by Andreas S. Franci Gonçalves
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid