Click here to Skip to main content
15,881,424 members
Articles / Desktop Programming / MFC
Article

Controlling console applications

Rate me:
Please Sign up or sign in to vote.
4.17/5 (9 votes)
4 Feb 2002Ms-PL2 min read 172.9K   3.1K   65   40
Run console applications and controll/use their input/output streams

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
{
public:
    explicit CSpawnConsumer1(CMyEdit* pEdit)
                                   : m_pEdit(pEdit){}
    void Consume(TCHAR* p, DWORD dw)
    {
        m_pEdit->DoWhateverWithTheInput(p);
    }

private:
    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.

Compatibility

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

License

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


Written By
Software Developer (Senior)
Portugal Portugal
Software Smith, Blacksmith, Repeat Founder, Austrian, Asgardian.

Comments and Discussions

 
Generalnon-starter for win9x/ME Pin
umeca7416-Sep-02 10:46
umeca7416-Sep-02 10:46 
GeneralRe: non-starter for win9x/ME Pin
Andreas Saurwein23-Sep-02 1:08
Andreas Saurwein23-Sep-02 1:08 
GeneralRedirecting existing process IO Pin
22-Aug-02 4:15
suss22-Aug-02 4:15 
GeneralRe: Redirecting existing process IO Pin
Andreas Saurwein26-Aug-02 1:02
sussAndreas Saurwein26-Aug-02 1:02 
GeneralWrong function! Pin
Nguyen Binh5-Aug-02 23:44
Nguyen Binh5-Aug-02 23:44 
GeneralRe: Wrong function! Pin
Andreas Saurwein6-Aug-02 2:22
Andreas Saurwein6-Aug-02 2:22 
GeneralRe: Wrong function! Pin
Jim Crafton22-Aug-02 8:25
Jim Crafton22-Aug-02 8:25 
General4k limitation Pin
18-Jun-02 5:23
suss18-Jun-02 5:23 
Why is 4k limitation?
First I thought there is problem in program and this line limit this:

bool CSpawn::CreateChildProcess()
{
...
...

TCHAR shellCmd[4096];
if (!GetEnvironmentVariable(_T("ComSpec"), shellCmd, 4096))
return FALSE;

...

but if I simply increase value 4096 to higher it's nothing change. So, what is solution for this limitation?



Bed / Placid
GeneralRe: 4k limitation Pin
Andreas Saurwein18-Jun-02 5:55
Andreas Saurwein18-Jun-02 5:55 
Generalillegal memory access in Release config (Non-Unicode). Pin
4-Mar-02 6:54
suss4-Mar-02 6:54 
GeneralRe: illegal memory access in Release config (Non-Unicode). Pin
Andreas Saurwein4-Mar-02 12:01
Andreas Saurwein4-Mar-02 12:01 
GeneralRe: illegal memory access in Release config (Non-Unicode). Pin
Blade[DMS]4-Mar-02 23:08
Blade[DMS]4-Mar-02 23:08 
GeneralVerry cool Pin
Jim Crafton8-Feb-02 8:44
Jim Crafton8-Feb-02 8:44 
Generaldirecting cout/stdout to window Pin
6-Feb-02 12:00
suss6-Feb-02 12:00 
GeneralRe: directing cout/stdout to window Pin
Andreas Saurwein6-Feb-02 12:10
Andreas Saurwein6-Feb-02 12: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.