What is the correct way to implement and architect a command line tool as a C# console application?
Concerns to address include proper parsing of command line variables, and the proper way to output text. While Console.WriteLine() is the most obvious choice for output, what are the circumstances in which one should instead opt to write to the standard error stream, .Error, .SetErrorStream, etc?
What is the proper way for the application to exit while returning a proper return code to the calling command?
How should the the CancelKeyPress event be implemented to interrupt the program? Is it only for use when an asynchronous operation is occurring on a separate thread?
Is there a concise guide to command line tool programming in C#, or even better an open source project or template which I could use to properly implement a relatively simple tool?
A standard conforming C implementation consists of a compiler that translates compilation units as mandated by the standard, an implementation of the standard library for all functions required by the standard and something (normally a linker) that puts everything together to build an executable file.
Compared to C++, C is the simpler and ultimately faster programming language. C is procedural and does not support classes and objects, meaning it has less functionality than C++. This allows you to spend more time focusing on what you can do with C's libraries, especially at the OS level.
Every C program has a primary (main) function that must be named main. If your code adheres to the Unicode programming model, you can use the wide-character version of main, wmain. The main function serves as the starting point for program execution.
Error messages should be written to stderr aka Console.Error, and normal output to stdout aka Console.Out. This is particularly important for "filter" type console apps whose output (stdout) can be piped to another process, e.g. in a batch file.
Generally if you encounter an error, write an error message to Console.Error and return a non-zero result. Or if it's an exception, just don't bother handling it.
To return a result code, you can either pass it as an argument to Environment.Exit, set the Environment.ExitCode property, or return a non-zero value from main.
For simple console apps I would:
have a helper class to parse the command line.
have a facade class that provides a testable API for the functionality implemented by your command line tool. Like most .NET APIs, this would normally throw an exception if an error occurs.
the main program simply uses the helper to parse the command line and calls the API passing the arguments passed from the command line. It optionally catches exceptions thrown from the API, logs them, writes a user-oriented error message to Console.Error and sets a non-zero return code.
But I wouln't consider this to be the one true way: there isn't really such a thing which is why you're unlikely to find the book you're looking for.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With