Chris's coding blog

CommandOptions - interactive console application command parser

August 08, 2010

This is a class based on the Novell Options class for easily parsing commands and their arguments for console applications that sit and wait for input. I’ve tried to keep it as elegant the Novel Options class, which is aimed at console applications that exit immediately. My adaption is for interactive apps, and restricts you to two types of handler methods - no arguments, and an array of strings as params.

The example below should help to illustrate what it does.

Example usage

static void Main(string[] args)
{
string input = "";
MyHandler handler = new MyHandler();
CommandOptions options = new CommandOptions();
options.Add("show", handler.Show)
.Add("name", v => handler.Name(v))
.Add("age", v => handler.Age(v))
while (input != "quit" && input != "exit")
{
if (input == "cls" || input == "clear")
{
System.Console.Clear();
}
else
{
if (!string.IsNullOrEmpty(input))
{
if (options.Parse(input))
{
System.Console.WriteLine(handler.OutputMessage);
}
else
{
System.Console.WriteLine("I didn't understand that command");
}
}
}
System.Console.Write(">");
input = System.Console.ReadLine();
}
}
public class MyHandler
{
public string OutputMessage { get; set; }
public void Show()
{
OutputMessage = "Do something with the Show command, list SQL tables for example";
}
public void Name(string[] args)
{
OutputMessage = string.Format("{0} is your name",args[0]));
}
public void Age(string[] args)
{
OutputMessage = string.Format("{0} is your age",args[0]);
}
}

Source

using System;
using System.Collections.Generic;
/// <summary>
/// A class for parsing commands inside a tool. Based on Novell Options class (http://www.ndesk.org/Options).
/// </summary>
public class CommandOptions
{
private Dictionary<string, Action<string[]>> _actions;
private Dictionary<string, Action> _actionsNoParams;
/// <summary>
/// Initializes a new instance of the <see cref="CommandOptions"/> class.
/// </summary>
public CommandOptions()
{
_actions = new Dictionary<string, Action<string[]>>();
_actionsNoParams = new Dictionary<string, Action>();
}
/// <summary>
/// Adds a command option and an action to perform when the command is found.
/// </summary>
/// <param name="name">The name of the command.</param>
/// <param name="action">An action delegate</param>
/// <returns>The current CommandOptions instance.</returns>
public CommandOptions Add(string name, Action action)
{
_actionsNoParams.Add(name, action);
return this;
}
/// <summary>
/// Adds a command option and an action (with parameter) to perform when the command is found.
/// </summary>
/// <param name="name">The name of the command.</param>
/// <param name="action">An action delegate that has one parameter - string[] args.</param>
/// <returns>The current CommandOptions instance.</returns>
public CommandOptions Add(string name, Action<string[]> action)
{
_actions.Add(name, action);
return this;
}
/// <summary>
/// Parses the text command and calls any actions associated with the command.
/// </summary>
/// <param name="command">The text command, e.g "show databases"</param>
public bool Parse(string command)
{
if (command.IndexOf(" ") == -1)
{
// No params
foreach (string key in _actionsNoParams.Keys)
{
if (command == key)
{
_actionsNoParams[key].Invoke();
return true;
}
}
}
else
{
// Params
foreach (string key in _actions.Keys)
{
if (command.StartsWith(key) && command.Length > key.Length)
{
string options = command.Substring(key.Length);
options = options.Trim();
string[] parts = options.Split(' ');
_actions[key].Invoke(parts);
return true;
}
}
}
return false;
}
}
view raw CommandOptions.cs hosted with ❤ by GitHub

csharpcommand-line

Chris Small

I'm Chris Small, a software engineer living and working in London. This is my tech blog. Find out more via GithubStackoverflowResume