Writing Console Applications in .Net
Peter Aitken
A console application does not make use of the visual interface capabilities of the Windows operating system. It runs at the DOS prompt, or command window, and its interactions with the user are limited to text input and output. It sounds pretty basic, and it is.
Why would anyone want to write a console application today? Aren’t they a technological dinosaur with no relevance in today’s world of snazzy graphical user interfaces? No — the fact is that console applications definitely have a place in the programmer’s toolbox. And, because they are supported as a project type in Visual Studio .Net, they are quite easy to create.
The term console comes from the days of the mainframe, when the computer itself was hidden away in an air-conditioned room; the users sat at remote terminals consisting of a video display and a keyboard. Together, the keyboard and display were called the console. The user could type text in, and the computer could display text. This limited interaction may seem archaic, but the fact is that some programs do not need more sophisticated input and output. In fact, some need none at all — you start them, they perform a task, and then
quit. Some examples of programs that need little or no interaction with the user are:
Copy all Excel and Word documents from your documents folder to a backup location.
Go through a database to archive all data that is more than a year old.
Convert all graphics files in a folder from one file format to another.
The technique of redirection provides even more flexibility for console applications. To understand redirection, you need to know about the standard input and standard output streams. Provided by the operating system, these streams provide the means for a console application to input and output text. The standard input and output streams are by default connected to the console, so that’s where a console application normally gets its input and sends its output. Using redirection, the standard input and output streams can be
connected to something other than the console.
The most useful type of redirection involves disk files — the program takes its input from a text file on disk, rather than from the keyboard, and its output goes to another disk file. Redirection can also send the output of out console application directly to the
input of another, Redirection provides for great flexibility in running console applications without user intervention. At the command prompt, you enable redirection as follows:
program > file The output of program goes to file instead of the console.
program >> file The output of program is appended to file instead of going to the console.
program < file The program takes its input from file rather than the console.
program < file1 > file2 The program takes its input from file1 and sends output to file2.
program1 | program2 The output of program1 is the input for program2.
You also have several choices as to how a console application is started. The traditional way — typing the program’s name at the command prompt — certainly works. You can also start a console application by double-clicking the program name in Windows Explorer or by using the Run dialog box. Perhaps most important, a console application can be started from another program, as you’ll see later in this chapter. Finally, you can schedule a console application to run using Windows Scheduler.
Structure of .Net Console Applications
When you create a new console application, Visual Studio creates a module with one procedure in it, named Main().
Main() is where execution starts. You will add code to Main(), of course, as well as adding additional procedures and even additional modules if needed. Your code has access to the full .Net class library. Naturally, you will not use any framework elements that require visual display.
Module Module1
Sub Main()
End Sub
End Module
The Console Class
At the heart of any console application is the Console class. This class is part of the System namespace, and it provides members for reading from the standard input stream and writing to the standard output stream. The class members that your use for input and output are described here:
Read(): Returns a type Integer representing the next character available from the standard input. Returns -1 if no character is available.
ReadLine(): Returns a string containing all the characters from standard input up to, but not including, the next carriage return (CR), line feed (LF), or CR/LF combination.
Write(exp): Writes exp to the standard output.
WriteLine(exp): Writes exp followed by a newline character to the standard output.
When inputting data from the keyboard, the Read() method does not return until the user presses Enter. Then, repeated calls to Read() return the numerical codes (ASCII) for the typed characters, one at a time, up to and including the codes for the CR/LF characters that represent pressing Enter (13 for the carriage return, 10 for the line feed). This is demonstrated by the console application the following listing. When you run this program, you will see how the characters you enter are input one at a time by the Read() method. Sample program output is shown in Figure 12.1.
Sub Main()
Dim i As Integer
Console.WriteLine("Enter some text then press Enter:")
Do While True
i = Console.Read
Console.WriteLine(i)
If i = 10 Then Exit Do
Loop
Console.Write("Press Enter to end program.")
Console.Read()
End Sub
Command Line Arguments
You can pass information to a console application when it is started by means of command-line arguments. A command-line argument is placed after the program name on the command line. For example, you could start the console application MyConsoleApp by typing the following at the command prompt:
myconsoleapp -c data.txt
The -c and the data.txt are command-line arguments and are available to code within the program. You can use command-line arguments to pass information to the program about what actions it is to carry out, what files it is to work with, and so on. Command-line arguments are separated from the program name and from one another by spaces. If an argument contains a space, enclose it in quotes, as in myconsoleapp -c "c:my documentsdata.txt". This permits the second argument to be treated as a single argument rather than as two separate arguments.
You use the Command() function to access command-line arguments in your code. This function returns a string containing all the text that was entered on the command line after the program name. It does not parse out the individual arguments; the program must do this by looking for spaces and double quotes in the returned string and extracting the individual arguments. You can find an example of this in the VB.Net online help in the section on the Command() function.
When testing a console application in the Visual Studio environment, you can specify its command line arguments. By default, a console application runs without command-line arguments when executed from within Visual Studio. To add one or more arguments, follow these steps:
In the Solution Explorer, select the project.
Select Property Pages from the View menu, or press Shift+F4, to open the project’s property page.
On the left side of the property page, select Debugging under Configuration Properties.
In the box labeled Command Line Arguments, enter one or more arguments separated by spaces, remembering to enclose an argument in double quotes if it contains a space.
Click OK. When you run the project, the specified arguments will be passed to your program just as if they had been entered at the command prompt.
Errors in Console Applications
A console application can generate runtime errors just like any other program. These should be handled with VB.Net’s error-handling statements. You can use either unstructured error-handling statements (On Error and Resume) or structured (Try, Catch, Finally). Unhandled errors have the same consequences as in any type of VB.Net program: The user sees an error message and then is given the option of debugging the program or quitting. Clearly, unhandled errors are to be avoided. Graceful error handling is an essential part of any application.
If an unhandled error occurs, console applications have an additional method of dealing with the error message. This operates in in parallel with the usual VB.Net response to unhandled errors, as described in the previous paragraph. Error messages in a console application are sent to an output stream called Standard Error. By default, Standard Error is connected to the console, so error messages appear on-screen. Redirecting Standard Input does
not redirect Standard Error. However, you can redirect Standard Error by calling the Console.SetError() method. Most often, error messages are redirected to file.
Redirection in Code
In addition to redirecting input and output using command line syntax, you can do so within your program by using the Console.SetIn() and Console.SetOut() methods. The syntax is as follows:
Console.SetIn(newIn As TextReader)
Console.SetOut(newOut As TextWriter)
TextReader and TextWriter are abstract classes and so cannot be implemented directly. You will use a derived class instead. For redirecting input and output to files, the technique is as follows:
Create a FileStream object for the desired file. Be sure the file mode is set appropriately depending on whether you will be reading from the file or writing to it.
Wrap the FileStream object in either a StreamReader object (for input) or a StreamWriter object (for output).
Pass the StreamReader object to the Console.SetIn() method, and pass the StreamWriter object to the Console.SetOut() method.
The program in the following listing demonstrates how to redirect both input and output to files. It doesn’t do anything particularly useful; it simply reads lines of text from the input, appends a few exclamation points, and then writes to the output. It requires that a text file named Input.txt be present in the same folder as the application. After the program
runs, a file named Output.txt will also be present, containing the program’s output.
Imports System
Imports System.IO
Sub Main()
Dim buf As String
Dim inFile As New FileStream("Input.txt", FileMode.Open)
Dim inStream As New StreamReader(inFile)
Dim outFile As New FileStream("Output.txt", FileMode.CreateNew)
Dim outStream As New StreamWriter(outFile)
Console.SetIn(inStream)
Console.SetOut(outStream)
buf = Console.ReadLine()
Do While Len(buf) > 0
buf = buf & "!!!"
Console.WriteLine(buf)
buf = Console.ReadLine()
Loop
inStream.Close()
outStream.Close()
End Sub
Summary
Console applications may seem old fashioned but they still have plenty of uses. They are easy to write thanks to the support provided in the .Net framework. They are definitely worth your consideration for any task that does not require interaction with the user.
Copyright © 2005 Ziff Davis Media Inc. All Rights Reserved. Originally appearing in Dev Source.