public int DispatchCommand(IReadOnlyCollection <IConsoleCommand> commands, string[] arguments, TextWriter consoleOut, bool skipExeInExpectedUsage = false) { IConsoleCommand selectedCommand = null; var console = consoleOut; foreach (var command in commands) { ValidateConsoleCommand(command); } try { List <string> remainingArguments; if (commands.Count == 1) { selectedCommand = commands.First(); if (arguments.Any() && string.Equals(arguments.First(), selectedCommand.Command, StringComparison.OrdinalIgnoreCase)) { remainingArguments = selectedCommand.GetActualOptions().Parse(arguments.Skip(1)); } else { remainingArguments = selectedCommand.GetActualOptions().Parse(arguments); } } else { if (!arguments.Any()) { throw new ConsoleHelpAsException("No arguments specified."); } if (arguments[0].Equals("help", StringComparison.OrdinalIgnoreCase)) { selectedCommand = GetMatchingCommand(commands, arguments.Skip(1).FirstOrDefault()); if (selectedCommand == null) { ConsoleHelp.ShowSummaryOfCommands(commands, console); } else { ConsoleHelp.ShowCommandHelp(selectedCommand, console, skipExeInExpectedUsage); } return(-1); } selectedCommand = GetMatchingCommand(commands, arguments.First()); remainingArguments = selectedCommand?.GetActualOptions().Parse(arguments.Skip(1)) ?? throw new ConsoleHelpAsException("Command name not recognized."); } selectedCommand.CheckRequiredArguments(); CheckRemainingArguments(remainingArguments, selectedCommand.RemainingArgumentsCount); var preResult = selectedCommand.OverrideAfterHandlingArgumentsBeforeRun(remainingArguments.ToArray()); if (preResult.HasValue) { return(preResult.Value); } ConsoleHelp.ShowParsedCommand(selectedCommand, console); return(selectedCommand.Run(remainingArguments.ToArray())); } catch (ConsoleHelpAsException e) { return(DealWithException(e, console, skipExeInExpectedUsage, selectedCommand, commands)); } catch (NDesk.Options.OptionException e) { return(DealWithException(e, console, skipExeInExpectedUsage, selectedCommand, commands)); } }