コード例 #1
0
 /// <summary>
 /// Writes a list of all the shell commands in the specified assembly to the standard output stream.
 /// </summary>
 /// <param name="assembly">The assembly that contains the shell commands.</param>
 /// <exception cref="ArgumentNullException">
 ///   <paramref name="assembly"/> is <see langword="null"/>.
 /// </exception>
 /// <remarks>
 /// <para>
 ///   This method writes a list of all shell command names and their descriptions to the standard output stream, wrapping
 ///   the lines to fit on the console automatically.
 /// </para>
 /// <para>
 ///   A command's name is retrieved from its <see cref="ShellCommandAttribute"/> attribute, and the description is retrieved
 ///   from its <see cref="DescriptionAttribute"/> attribute.
 /// </para>
 /// <para>
 ///   Line wrapping at word boundaries is applied to the output, wrapping at the console's window width. When the console output is
 ///   redirected to a file, Microsoft .Net will still report the console's actual window width, but on Mono the value of
 ///   the <see cref="Console.WindowWidth"/> property will be 0. In that case, the usage information will not be wrapped.
 /// </para>
 /// <para>
 ///   This method indents additional lines for the command descriptions, unless the <see cref="Console.WindowWidth"/> property is less than 31.
 /// </para>
 /// </remarks>
 public static void WriteAssemblyCommandListToConsole(Assembly assembly)
 {
     using (LineWrappingTextWriter writer = LineWrappingTextWriter.ForConsoleOut())
     {
         WriteAssemblyCommandList(writer, assembly);
     }
 }
コード例 #2
0
        /// <summary>
        /// Finds and instantiates the shell command with the specified name, or if that fails, writes error and usage information to the specified writers.
        /// </summary>
        /// <param name="assembly">The assembly to search for the shell command.</param>
        /// <param name="commandName">The name of the command.</param>
        /// <param name="args">The arguments to the shell command.</param>
        /// <param name="index">The index in <paramref name="args"/> at which to start parsing the arguments.</param>
        /// <param name="options">The options to use.</param>
        /// <returns>An instance a class deriving from <see cref="ShellCommand"/>, or <see langword="null"/> if the command was not found or an error occurred parsing the arguments.</returns>
        /// <exception cref="ArgumentNullException">
        ///   <paramref name="assembly"/>, <paramref name="args"/>, or <paramref name="options"/> is <see langword="null"/>
        /// </exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> does not fall inside the bounds of <paramref name="args"/>.</exception>
        /// <remarks>
        /// <para>
        ///   If the command could not be found, a list of possible commands is written to <see cref="CreateShellCommandOptions.Out"/>. If an error occurs parsing the command's arguments, the error
        ///   message is written to <see cref="CreateShellCommandOptions.Error"/>, and the shell command's usage information is written to <see cref="CreateShellCommandOptions.Out"/>.
        /// </para>
        /// <para>
        ///   If the <see cref="CreateShellCommandOptions.Out"/> property or <see cref="CreateShellCommandOptions.Error"/> property is <see langword="null"/>, output
        ///   is written to the standard output and error streams respectively, with line wrapping at word boundaries applied to the output, wrapping at the console's window width. When the console output is
        ///   redirected to a file, Microsoft .Net will still report the console's actual window width, but on Mono the value of
        ///   the <see cref="Console.WindowWidth"/> property will be 0. In that case, the usage information will not be wrapped.
        /// </para>
        /// <para>
        ///   If the <see cref="CreateShellCommandOptions.Out"/> property or <see cref="CreateShellCommandOptions.Error"/> property are instance of the
        ///   <see cref="LineWrappingTextWriter"/> class, this method indents additional lines for the usage syntax and argument descriptions according
        ///   to the values specified by the <see cref="CreateShellCommandOptions"/>, unless the <see cref="LineWrappingTextWriter.MaximumLineLength"/> property is less than 30.
        /// </para>
        /// </remarks>
        public static ShellCommand CreateShellCommand(Assembly assembly, string commandName, string[] args, int index, CreateShellCommandOptions options)
        {
            if (assembly == null)
            {
                throw new ArgumentNullException("assembly");
            }
            if (args == null)
            {
                throw new ArgumentNullException("args");
            }
            if (index < 0 || index > args.Length)
            {
                throw new ArgumentOutOfRangeException("index");
            }
            if (options == null)
            {
                throw new ArgumentNullException("options");
            }

            bool       disposeOut   = false;
            bool       disposeError = false;
            TextWriter output       = options.Out;
            TextWriter error        = options.Error;

            try
            {
                if (output == null)
                {
                    disposeOut  = true;
                    output      = LineWrappingTextWriter.ForConsoleOut();
                    options.Out = output;
                }
                if (error == null)
                {
                    disposeError  = true;
                    error         = LineWrappingTextWriter.ForConsoleError();
                    options.Error = error;
                }

                Type commandType = commandName == null ? null : GetShellCommand(assembly, commandName, options.CommandNameComparer);
                if (commandType == null)
                {
                    WriteShellCommandListUsage(output, assembly, options);
                }
                else if (CommandUsesCustomArgumentParsing(commandType))
                {
                    return((ShellCommand)Activator.CreateInstance(commandType, args, index, options));
                }
                else
                {
                    CommandLineParser parser = new CommandLineParser(commandType, options.ArgumentNamePrefixes, options.ArgumentNameComparer)
                    {
                        AllowDuplicateArguments       = options.AllowDuplicateArguments,
                        AllowWhiteSpaceValueSeparator = options.AllowWhiteSpaceValueSeparator,
                    };
                    ShellCommand command = null;
                    try
                    {
                        command = (ShellCommand)parser.Parse(args, index);
                    }
                    catch (CommandLineArgumentException ex)
                    {
                        error.WriteLine(ex.Message);
                        error.WriteLine();
                    }

                    if (command == null)
                    {
                        string originalPrefix = options.UsageOptions.UsagePrefix;
                        options.UsageOptions.UsagePrefix += " " + GetShellCommandName(commandType);
                        // If we're writing this to the console, output should already by a LineWrappingTextWriter, so the max line length argument here is ignored.
                        parser.WriteUsage(output, 0, options.UsageOptions);
                        options.UsageOptions.UsagePrefix = originalPrefix;
                    }
                    else
                    {
                        return(command);
                    }
                }

                return(null);
            }
            finally
            {
                if (disposeOut && output != null)
                {
                    output.Dispose();
                }
                if (disposeError && error != null)
                {
                    error.Dispose();
                }
            }
        }