using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Text.RegularExpressions;
namespace Kurapaty.Solutions.Utils
{
///
/// Commandline Arguments Parser class
///
///
/// Source:
///
public class Arguments
{
///
/// Splits the command line. When main(string[] args) is used escaped quotes (ie a path “c:\folder\”)
/// Will consume all the following command line arguments as the one argument.
/// This function ignores escaped quotes making handling paths much easier.
///
/// The command line. ///
public static string[] SplitCommandLine(string commandLine)
{
var translatedArguments = new StringBuilder(commandLine);
var escaped = false;
for (var i = 0; i < translatedArguments.Length; i++)
{
if (translatedArguments[i] == '"')
{
escaped = !escaped;
}
if (translatedArguments[i] == ' ' && !escaped)
{
translatedArguments[i] = '\n';
}
}
var toReturn = translatedArguments.ToString().Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
for (var i = 0; i < toReturn.Length; i++)
{
toReturn[i] = RemoveMatchingQuotes(toReturn[i]);
}
return toReturn;
}
public static string RemoveMatchingQuotes(string stringToTrim)
{
var firstQuoteIndex = stringToTrim.IndexOf('"');
var lastQuoteIndex = stringToTrim.LastIndexOf('"');
while (firstQuoteIndex != lastQuoteIndex)
{
stringToTrim = stringToTrim.Remove(firstQuoteIndex, 1);
stringToTrim = stringToTrim.Remove(lastQuoteIndex - 1, 1); //-1 because we’ve shifted the indicies left by one
firstQuoteIndex = stringToTrim.IndexOf('"');
lastQuoteIndex = stringToTrim.LastIndexOf('"');
}
return stringToTrim;
}
private readonly Dictionary> _parameters;
private string _waitingParameter;
public Arguments(IEnumerable arguments)
{
_parameters = new Dictionary>();
string[] parts;
//Splits on beginning of arguments ( – and — and / )
//And on assignment operators ( = and : )
var argumentSplitter = new Regex(@"^-{1,2}|^/|=|:", RegexOptions.IgnoreCase | RegexOptions.Compiled);
foreach (var argument in arguments)
{
parts = argumentSplitter.Split(argument, 3);
switch (parts.Length)
{
case 1:
AddValueToWaitingArgument(parts[0]);
break;
case 2:
AddWaitingArgumentAsFlag();
//Because of the split index 0 will be a empty string
_waitingParameter = parts[1];
break;
case 3:
AddWaitingArgumentAsFlag();
//Because of the split index 0 will be a empty string
string valuesWithoutQuotes = RemoveMatchingQuotes(parts[2]);
AddListValues(parts[1], valuesWithoutQuotes.Split(','));
break;
}
}
AddWaitingArgumentAsFlag();
}
private void AddListValues(string argument, IEnumerable values)
{
foreach (var listValue in values)
{
Add(argument, listValue);
}
}
private void AddWaitingArgumentAsFlag()
{
if (_waitingParameter == null) return;
AddSingle(_waitingParameter, "true");
_waitingParameter = null;
}
private void AddValueToWaitingArgument(string value)
{
if (_waitingParameter == null) return;
value = RemoveMatchingQuotes(value);
Add(_waitingParameter, value);
_waitingParameter = null;
}
///
/// Gets the count.
///
/// The count.
public int Count
{
get
{
return _parameters.Count;
}
}
///
/// Adds the specified argument.
///
/// The argument. /// The value. public void Add(string argument, string value)
{
if (!_parameters.ContainsKey(argument))
_parameters.Add(argument, new Collection());
_parameters[argument].Add(value);
}
public void AddSingle(string argument, string value)
{
if (!_parameters.ContainsKey(argument))
_parameters.Add(argument, new Collection());
else
throw new ArgumentException(string.Format("Argument {0} has already been defined", argument));
_parameters[argument].Add(value);
}
public void Remove(string argument)
{
if (_parameters.ContainsKey(argument))
_parameters.Remove(argument);
}
///
/// Determines whether the specified argument is true.
///
/// The argument. ///
/// true if the specified argument is true; otherwise, false .
///
public bool IsTrue(string argument)
{
AssertSingle(argument);
var arg = this[argument];
return arg != null && arg[0].Equals("true", StringComparison.OrdinalIgnoreCase);
}
public bool IsExists(string argument)
{
return IsTrue(argument);
}
private void AssertSingle(string argument)
{
if (this[argument] != null && this[argument].Count > 1)
throw new ArgumentException(string.Format("{0} has been specified more than once, expecting single value", argument));
}
public string Single(string argument)
{
AssertSingle(argument);
//only return value if its NOT true, there is only a single item for that argument
//and the argument is defined
if (this[argument] != null && !IsTrue(argument))
return this[argument][0];
return null;
}
public bool Exists(string argument)
{
return (this[argument] != null && this[argument].Count > 0);
}
///
/// Gets the with the specified parameter.
///
///
public Collection this[string parameter]
{
get
{
return _parameters.ContainsKey(parameter) ? _parameters[parameter] : null;
}
}
}
}
Usage:
private bool ProcessCommandLineParameters()
{
// Usage: -ec -source:"C:\Temp\formDefinition.txt" -target:"C:\Temp\formDefinition.enc"
try
{
Arguments parser = new Arguments(Arguments.SplitCommandLine(Environment.CommandLine));
if (parser.IsExists("help") || parser.IsExists("?"))
ShowUsageHelpMessage();
if (parser.Exists("source") && 1 == parser["source"].Count) tbSource.Text = parser.Single("source");
if (parser.Exists("target") && 1 == parser["target"].Count) tbTarget.Text = parser.Single("target");
if (parser.Exists("ec") && parser.IsTrue("ec"))
{
button1_Click(null, null);
return true;
}
if (parser.Exists("dc") && parser.IsTrue("dc"))
{
button2_Click(null, null);
return true;
}
}
catch (Exception)
{
MessageBox.Show("Invalid commandline arguments passed. Please use GUI or type \"help\" at commandline.",
"Commandline processor", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
return false;
}