⬆️ ⬇️

Work with Command Line in .Net

Good day community,



For a long time I was just a reader of useful technical articles.

I think it's my time to write my first post. I hope that this post which will be useful not only to novice .net developers.



It seems to me that this seemingly banal topic receives little attention. In this article I would like to share my experience with the Command Line in .Net.



Why, I chose this topic, very often in universities students are told about command line parameters
static void Main(string[] args) 


and then give tasks that sound like this: “ Write application A that will take the parameters X, Y, Z, perform the action and display them on the screen ... ”.

Then, usually, it turns out approximately the following code:

 class MainClass { static int Main(string[] args) { // Test if input arguments were supplied: if (args.Length == 0) { System.Console.WriteLine("Please enter a numeric argument."); System.Console.WriteLine("Usage: Factorial <num>"); return 1; } try { // Convert the input arguments to numbers: int num = int.Parse(args[0]); System.Console.WriteLine("The Factorial of {0} is {1}.", num, Functions.Factorial(num)); return 0; } catch (System.FormatException) { System.Console.WriteLine("Please enter a numeric argument."); System.Console.WriteLine("Usage: Factorial <num>"); return 1; } } } 


')

Everything seems to be fine, but the more parameters, the more type strings appear

 int num = int.Parse(args[]); 
where X is the parameter number.



In most cases, people get used to this type of reading parameters. Having come to a real project, and getting the task, write a small console application that will do something with certain parameters, work with parameters in the same way.

But in real-world applications of command-line parameters, there can be a great many, and their order should not be of particular importance to the user.

But even in many real-world products, in Kratz, the essence of reading command line parameters comes down to working with the mass string [] args.



I also wrote and saw many options for reading parameters, and one day I found a beautiful implementation of reading parameters that suits me completely, this is the Command Line Parser Library.



What is she good at?



And the beauty of its use is only 3 steps:
  1. Creating a custom class with a set of public fields that will be our parameters
  2. Using the Option attribute above each variable to create its description.
  3. The very use of CommandLineParser.
 public enum OptimizeFor { Unspecified, Speed, Accuracy } public sealed class Options : CommandLineOptionsBase { #region Standard Option Attribute [Option("r", "read", Required = true, HelpText = "Input file with data to process.")] public string InputFile = String.Empty; [Option("w", "write", HelpText = "Output file with processed data (otherwise standard output).")] public string OutputFile = String.Empty; [Option("j", "jump", HelpText = "Data processing start offset.")] public double StartOffset = 0; [Option(null, "optimize", HelpText = "Optimize for Speed|Accuracy.")] public OptimizeFor Optimization = OptimizeFor.Unspecified; #endregion #region Specialized Option Attribute [ValueList(typeof(List<string>))] public IList<string> DefinitionFiles = null; [OptionList("o", "operators", Separator = ';', HelpText = "Operators included in processing (+;-;...)." + " Separate each operator with a semicolon." + " Do not include spaces between operators and separator.")] public IList<string> AllowedOperators = null; [HelpOption(HelpText = "Dispaly this help screen.")] public string GetUsage() { var help = new HelpText(Program._headingInfo); help.AdditionalNewLineAfterOption = true; help.Copyright = new CopyrightInfo("Giacomo Stelluti Scala", 2005, 2009); this.HandleParsingErrorsInHelp(help); help.AddPreOptionsLine("This is free software. You may redistribute copies of it under the terms of"); help.AddPreOptionsLine("the MIT License <http://www.opensource.org/licenses/mit-license.php>."); help.AddPreOptionsLine("Usage: SampleApp -rMyData.in -wMyData.out --calculate"); help.AddPreOptionsLine(string.Format(" SampleApp -rMyData.in -i -j{0} file0.def file1.def", 9.7)); help.AddPreOptionsLine(" SampleApp -rMath.xml -wReport.bin -o *;/;+;-"); help.AddOptions(this); return help; } private void HandleParsingErrorsInHelp(HelpText help) { string errors = help.RenderParsingErrorsText(this); if (!string.IsNullOrEmpty(errors)) { help.AddPreOptionsLine(string.Concat(Environment.NewLine, "ERROR: ", errors, Environment.NewLine)); } } } 


As you can see from the example, the library helps to parse any type of parameters, and it helps to simply create help for working with the command line.



The actual work with parsingo looks like this:

  private static void Main(string[] args) { var options = new Options(); ICommandLineParser parser = new CommandLineParser(); if (!parser.ParseArguments(args, options)) Environment.Exit(1); DoCoreTask(options); Environment.Exit(0); } 




As you can see, the use of this approach carries a lot of positive points in the form of readability, testability, support, etc.



Thank you, I hope, my first “pancake” came out not as a lump, but an executable.



Links to the library and examples are taken from:

MSDN: http://msdn.microsoft.com/en-us/library/cb20e19t(v=vs.80).aspx

Command Line Parser Library: Command Line Parser Library

Source: https://habr.com/ru/post/141987/



All Articles