Introduction

As developers, every so often we have to kick off some command line programs. Compiling and building tools, utilities,and so on.
Recently I have been writing a small application that calls Oracle's 'impdp' and 'expdp' tools for you. While working on it I thought - it'd be nice to see the console
program running, but inside my application. This article shows you how to create a Console Control that lets you do just that.

Using the Control

Tip: Use Nuget! Install the package ConsoleControl for WinForms or ConsoleControl.WPF for WPF.

If you just need the control, download the binary and sample application and add a reference to
ConsoleControl.dll. You'll get the ConsoleControl
in the toolbox, drop it into a Form, and you're done. The key function is:

StartProcess(string fileName, string arguments)

This function starts the process specified by fileName. It will use the arguments supplied. The process will run, but its output will be sent to the console control.
The console control can also take input from the keyboard.

Some other useful functions are:

StopProcess

Kills the running process.

WriteOutput(string output, Color color)

Writes the string 'output' to the console window, using the specified color.

WriteInput(string input, bool echo, Color color)

Writes the string 'input' to the running process' input stream. If 'echo' is true, then the input will also be written to the Console Control (as if the user had keyed it in).

ShowDiagnostics

If this property is set to true, diagnostics will be shown. These include:

A message saying 'Running X' when you start a process.

A message saying 'X exited.' when a process ends.

Exceptions written in red if the process cannot be run.

IsInputEnabled

If this property is set to true, then the user can type input into the console window.

IsProcessRunning

This property evaluates to true if the the process is currently running.

CurrentProcess

The current running process (if any).

InternalRichTextBox

Returns the rich text box which displays the console output.

How Does It Work?

Essentially all we need to do to get the required functionality, is create a process and have direct access to its input and output streams.
Here's how we can do that. Create a new User Control named 'ConsoleControl' and add a rich text box to the UserControl. Now we'll create the most key function -
StartProcess:

The first thing we do is create the process start info. To make sure that it doesn't show a window, we make sure
CreateNoWindow is set to true.
We will also specify that we're redirecting standard output, standard error, and standard input.

Now that we have the process start info, we can actually start the process. We also store the file name and arguments for later. The class must also contain two background workers,
to read the output stream and error stream. Now we start them - and enable editing if the
IsInputEnabled flag is on. We also store the standard input, output and error streams.

All we are doing here is reading from the specified buffer. We then use the 'ReportProgress' function of the worker to tell the control to update the screen.
The Report Progress event handler works as below:

The event handler is trivial - we just cast the data and write the output.
Writing the output is just a case of adding the text to the rich text box. inputStart
is also updated - this lets us keep track of where the user can type. This is
used in the KeyDown event of the internal rich text box, as we see below.

If the selection is before the input start, we don't let the user enter text. If the return key is pressed, we write it to the output stream.

This is the bulk of the code - as you can see, it is not complex, but it does the job.

Final Thoughts

This control is basic - it may support what you need, if not do feel free to use it as a baseline for your own projects. Some things that the control doesn't do are listed below:

Restrict output to 80 characters horizontally.

Respect changes to the console foreground and background.

Support programmatic clear-screen etc.. Remember - we're streaming output, if you need to run a program that manipulates the console, this is not the control for you!

Ctrl-C

There has been quite some discussion in the messages about the complexity of sending a command like 'Control C' to a cmd process in the console window. Just so that others can find the solution until something formal is actually published, VisualG seems to have a good solution which you can find here:

No probs - do you need to change the font of the WPF or WinForms control? For winforms, download the source code and simply set the 'Font' property of the internal richtextbox. For WPF, go to the control template and do the same, if you're not sure how to do this let me know and I'll update the article with this info.

i was download the source code WinForms control and try change the font from font property,consolecontrol but me no lucky.
what you mean with richtextbox is consolecontrol(black box) right?
thanks for respon me

I've just updated the source code in the article, changing the the font on the WinForms ConsoleControl will change the font on the internal edit control, and the same with the WPF one. So get the latest source code and change the font property, then you're good to go

StartProcess takes only two arguments - the path to the executable and then the arguments, so if you want to pass arguments to your test process, you'll need to create a single string for the arguments, and pass that, a bit like:

If this is for a study project, make sure you understand what is going on at each stage, for example:

1. Why is an '@' ampersand symbol used in the first string I created?
2. How does 'string.Format' work?
3. What if textBox1.Text is a file path that contains spaces - will the arguments still parse correctly?

Just make sure that you look up each of the points so that you understand the changes you're making

Thats work perfectly
many thanks again
about three question,
1. '@' used for dir path file.(correct me if i wrong)
2. i dont know.
3. i was test with rename folder Aproject to Aproject-a and the code doesn't work.

actually this project build for load aplication modul to the device.
I think to able create useful tool for that.
I have long wanted to learn programming but I do n't know where to start.
and i am found your useful article according to what I thinked
I hope this can make me better and better.
GBU..

Although in the sample you can see that we are running a CMD window, the control itself is designed to run any console based application. For example, you could use it to automate (and visualise) something like the Oracle impdp tool - it's not a replacement for the console! In cases where you're doing advanced console stuff, powershell is indeed very useful - this is a control library for developers to use, not a command line replacement

Did you manage to solve (Ctrl+C issue - To stop a lengthy operation) ? I am doing it in a round about fashion and don't think it's a good idea.. I am killing the process and restarting it again. This involves a lot of overhead.. for example i have to navigate him/her to the last directory he/she was working on after restarting the process .. Total waste..