|Using the Console|
|Written by Harry Fairhead|
|Monday, 21 March 2011|
Have you ever wanted to open a console in the middle of an application that doesn't usually support one? This article explains exactly how to master the console.
The console is a bit of a mystery to many .NET programmers.
You can create a console application very easily and there is a Console class which allows you to interact with the user at a very basic level.
The problems start when you are in the middle of some non-console-based project and suddenly it would be useful to pop-up a console window.
You might think, given that there is a Console class, that this should be easy. All you should have to do is create an instance of Console and start using it.
Of course when you look at the situation a little more carefully this isn't possible because Console is a static class and hence there is no way of creating an instance. At this point you might be tempted to give up and program your own class using a form of some kind, but it is possible to use a console in any application including a .NET forms or WPF application.
The first thing to realise is that the console window is provided by the operating system not the .NET framework. It’s the command prompt that you use to do jobs that can't easily be achieved via the usual GUI.
There are OS native API calls which create and destroy the console and these are used in the .NET Console application template to provide a console for the Console class to wrap.
As there can be only one console attached to a process at any one time the Console class works in a very simple way. When you reference any Console method it simply makes use of the currently attached console. So in principle if you manually create a console you should be able to use the Console static class to work with it and so avoid having to create your own wrapper.
The console API
The console API is very simple. There is an API call that will create and attach a new console:
[DllImport("kernel32",SetLastError = true)]
If it is successful it returns true and generally the only reason for it to fail is that the process already has a console attached. If you want to discover the error code that the call generated use the .NET method:
If a console already exists and is attached to another process you can attach it to the current process using:
[DllImport("kernel32.dll", SetLastError = true)]
In most cases the console that you want to attach belongs to the parent process and to do this you can use the constant:
const uint ATTACH_PARENT_PROCESS= 0x0ffffffff;
There is also a FreeConsole API call that will dispose of any currently attached console:
[DllImport("kernel32.dll", SetLastError = true,
There is also a long list of other console API calls but in the main you don't need these because the Console class provides you with managed alternatives. For example, there is a Set and Get ConsoleTitle API call, but the Console property Title does the same job by calling the API for you.
Putting theory into practice is very easy. First you need to make sure you have all the necessary declarations:
A single method is all we need to either create or attach an existing console:
public void MakeConsole()
You can add some error handling to this to make it more robust but if there is an error the only consequence is that the Console class subsequently doesn’t work.
To test it out try:
This makes the console beep, changes its title and writes some suitable messages.
There is one small subtle "gotcha" that you need to keep in mind.
If you generate the console yourself then the user cannot redirect input/output from/to a file.
That is, if your application is MyApp.exe then
MyApp > MyTextFile.txt
works if MyApp is a console application but doesn't work if you create the console.
What you have to do in this case is detect the arguments "> MyTextFile.txt" when your application creates the console. For example, to redirect the output file you would use:
public void MakeConsole()
This uses the Environment object to retrieve the command line arguments and then tests for an output redirection in cmd.
If it finds a ">" it then creates a FileStream and then a StreamWriter which it sets the standard output to.
From this point on everything sent to the Console is stored in the file. The only complication is that you have to remember to close the file when the application is finished with the console. For example:
Of course a better design would be to put the Out.Close in a finalise method.
You can write similar code to redirect the standard input stream and even to form pipes and interpret other strange command line syntax.
|Last Updated ( Monday, 21 March 2011 )|