public static void Main(string[] args) { try { var commands = new Dictionary <String, Tuple <CommandAttribute, Type> >(); foreach (var type in System.Reflection.Assembly.GetExecutingAssembly().GetTypes()) { var commandAttribute = type.GetCustomAttributes(true).FirstOrDefault(a => a is CommandAttribute) as CommandAttribute; if (commandAttribute != null) { commands[commandAttribute.Name] = Tuple.Create(commandAttribute, type); } } var pipedArguments = new Dictionary <String, Object>(); var iterator = new CommandLineIterator(args, 0); while (!iterator.AtEnd()) { var commandName = iterator.Peek().Replace("+", ""); var command = commands.Values.FirstOrDefault(c => c.Item1.Name == commandName || c.Item1.Synonyms.Contains(commandName)); if (command == null) { throw new InvalidOperationException("Unknown command " + iterator.Peek()); } iterator = ParseCommand(command, iterator, pipedArguments); } } catch (Exception e) { Console.WriteLine(e.Message); Console.WriteLine(e.StackTrace); } finally { Console.ResetColor(); } }
private static CommandLineIterator ParseCommand(Tuple <CommandAttribute, Type> Command, CommandLineIterator Iterator, Dictionary <String, Object> PipedArguments) { var commandObject = Activator.CreateInstance(Command.Item2) as ICommand; try { Iterator = Iterator.Advance(); // Skip the command name. // Set the piped arguments. foreach (var pipedArgument in PipedArguments) { foreach (var member in commandObject.GetType().GetFields()) { if (member.Name == pipedArgument.Key && member.FieldType == pipedArgument.Value.GetType()) { member.SetValue(Command, pipedArgument.Value); } } } var defaultList = new List <Tuple <DefaultSwitchAttribute, System.Reflection.FieldInfo> >(); System.Reflection.FieldInfo unknownSwitch = null; var unknownSwitchCaught = false; foreach (var member in commandObject.GetType().GetFields()) { var defaultAttribute = member.GetCustomAttributes(true).FirstOrDefault(a => a is DefaultSwitchAttribute) as DefaultSwitchAttribute; if (defaultAttribute != null) { defaultList.Add(Tuple.Create(defaultAttribute, member)); } if (member.GetCustomAttributes(true).Any(a => a is UnknownSwitchAttribute)) { unknownSwitch = member; } } defaultList = defaultList.OrderBy(t => t.Item1.Order).ToList(); while (!Iterator.AtEnd() && !Iterator.Peek().StartsWith("+")) { if (Iterator.Peek().StartsWith("-")) { var memberName = Iterator.Peek().Substring(1); Iterator = Iterator.Advance(); bool matchingMemberFound = false; foreach (var member in commandObject.GetType().GetFields()) { if (member.Name == memberName) { if (member.FieldType == typeof(bool)) { member.SetValue(commandObject, true); } else if (member.FieldType == typeof(String) && member.GetCustomAttributes(true).Any(a => a is GreedyArgumentAttribute)) { var v = ""; while (!Iterator.AtEnd()) { v += Iterator.Peek(); Iterator = Iterator.Advance(); if (!Iterator.AtEnd()) { v += " "; } } member.SetValue(commandObject, v); } else { member.SetValue(commandObject, ConvertArgument(Iterator.Peek(), member.FieldType)); Iterator = Iterator.Advance(); } matchingMemberFound = true; } } if (!matchingMemberFound) { if (unknownSwitch == null) { throw new InvalidOperationException("Unknown switch " + memberName); } else { if (unknownSwitchCaught) { throw new InvalidOperationException("Caught multiple unknown switches. " + memberName); } unknownSwitchCaught = true; unknownSwitch.SetValue(commandObject, ConvertArgument(memberName, unknownSwitch.FieldType)); } } } else { if (defaultList.Count == 0) { break; } if (defaultList[0].Item2.FieldType == typeof(String) && defaultList[0].Item2.GetCustomAttributes(true).Any(a => a is GreedyArgumentAttribute)) { var v = ""; while (!Iterator.AtEnd()) { v += Iterator.Peek(); Iterator = Iterator.Advance(); if (!Iterator.AtEnd()) { v += " "; } } defaultList[0].Item2.SetValue(commandObject, v); } else { defaultList[0].Item2.SetValue(commandObject, ConvertArgument(Iterator.Peek(), defaultList[0].Item2.FieldType)); Iterator = Iterator.Advance(); } defaultList.RemoveAt(0); } } commandObject.Invoke(PipedArguments); return(Iterator); } catch (Exception e) { Console.WriteLine(e.Message); Console.WriteLine(e.StackTrace); Console.WriteLine("Try 'help -" + Command.Item1.Name + "'"); if (!String.IsNullOrEmpty(Command.Item1.ErrorText)) { Console.WriteLine(Command.Item1.ErrorText); } Environment.Exit(0); throw new Exception(); } }