Beispiel #1
0
        /// <summary>
        /// Run command on <paramref name="type"/> and return exit code of executed command.
        /// </summary>
        /// <param name="type">Type to look for commands on.</param>
        /// <param name="arguments">List of command line arguments. First positional parameter is treated as command's name.</param>
        /// <param name="defaultCommandName">Default command name if no command name is specified as first parameter of <paramref name="arguments"/>.</param>
        /// <returns>Exit code of command-or-<see cref="DotNetExceptionExitCode"/> if exception happened-or-<see cref="BindFailureExitCode"/> if command not found and description is shown.</returns>
        public static int Run(Type type, CommandLineArguments arguments, string defaultCommandName = null)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }
            if (arguments == null)
            {
                throw new ArgumentNullException("arguments");
            }

            try
            {
                var bindResult = BindMethod(type, defaultCommandName, arguments);

                if (bindResult.IsSuccess)
                {
                    return((int)bindResult.Method.Invoke(null, bindResult.Arguments));
                }
                else
                {
                    var bestMatchMethod = (from bindingKeyValue in bindResult.FailedMethodBindings
                                           let parameters = bindingKeyValue.Value
                                                            let method = bindingKeyValue.Key
                                                                         orderby parameters.Count(parameter => parameter.IsSuccess) descending
                                                                         select method).FirstOrDefault();

                    var error = default(CommandLineException);
                    if (bestMatchMethod == null)
                    {
                        error = CommandLineException.CommandNotFound(bindResult.MethodName);
                    }
                    else
                    {
                        error = CommandLineException.InvalidCommandParameters(bestMatchMethod, bindResult.FailedMethodBindings[bestMatchMethod]);
                    }

                    if (DescribeOnBindFailure)
                    {
                        if (bindResult.MethodName == UnknownMethodName)
                        {
                            Console.WriteLine(" Error:");
                            Console.WriteLine("  No command is specified.");
                            Console.WriteLine();

                            if (WriteWholeErrorMessageOnBindFailure)
                            {
                                Console.Error.WriteLine(error);
                                Console.Error.WriteLine();
                            }

                            Describe(type);
                        }
                        else if (bestMatchMethod != null)
                        {
                            Console.WriteLine(" Error:");
                            Console.WriteLine(string.Format("  Invalid parameters specified for '{0}' command.", bindResult.MethodName));
                            Console.WriteLine();

                            if (WriteWholeErrorMessageOnBindFailure)
                            {
                                Console.Error.WriteLine(error);
                                Console.Error.WriteLine();
                            }

                            Describe(type, bindResult.MethodName);
                        }
                        else
                        {
                            Console.WriteLine(" Error:");
                            Console.WriteLine(error.Message);
                            Console.WriteLine();
                        }
                    }
                    else
                    {
                        throw error;
                    }
                }

                return(BindFailureExitCode);
            }
            catch (Exception exception)
            {
                var handler = UnhandledException ?? DefaultUnhandledExceptionHandler;
                handler(null, new ExceptionEventArgs(exception));

                return(DotNetExceptionExitCode);
            }
        }