コード例 #1
0
        /// <summary>
        /// Writes a list of all the shell commands in the specified assembly to the specified <see cref="TextWriter"/> using the specified formatting options.
        /// </summary>
        /// <param name="writer">The <see cref="TextWriter"/> to write the commands to.</param>
        /// <param name="assembly">The assembly that contains the shell commands.</param>
        /// <param name="commandFormat">The format string used to format a command's name and description, for example "{0,13} : {1}".</param>
        /// <exception cref="ArgumentNullException">
        ///   <paramref name="writer"/>, <paramref name="assembly"/> or <paramref name="commandFormat"/> is <see langword="null"/>.
        /// </exception>
        /// <remarks>
        /// <para>
        ///   The <paramref name="commandFormat"/> should have two placeholders, which are used for the command name and description respectively.
        /// </para>
        /// <para>
        ///   This method writes a list of all shell command names and their descriptions to <paramref name="writer"/>.
        /// </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>
        ///   If <paramref name="writer"/> is a <see cref="LineWrappingTextWriter"/>, the writer's indent will be reset before every
        ///   command. It is recommended to set the <see cref="LineWrappingTextWriter.Indent"/> property to a value appropriate for
        ///   your <paramref name="commandFormat"/>.
        /// </para>
        /// </remarks>
        public static void WriteAssemblyCommandList(TextWriter writer, Assembly assembly, string commandFormat)
        {
            if (writer == null)
            {
                throw new ArgumentNullException("writer");
            }
            if (assembly == null)
            {
                throw new ArgumentNullException("assembly");
            }
            if (commandFormat == null)
            {
                throw new ArgumentNullException("commandFormat");
            }

            LineWrappingTextWriter lineWriter = writer as LineWrappingTextWriter;

            Type[] commandTypes = GetShellCommands(assembly);
            foreach (Type commandType in commandTypes)
            {
                string name        = GetShellCommandName(commandType);
                string description = GetShellCommandDescription(commandType);

                if (lineWriter != null)
                {
                    lineWriter.ResetIndent();
                }
                writer.WriteLine(commandFormat, name, description ?? string.Empty);
            }
        }
コード例 #2
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);
     }
 }
コード例 #3
0
        /// <summary>
        /// Writes a list of all the shell commands in the specified assembly to the specified <see cref="TextWriter"/>.
        /// </summary>
        /// <param name="writer">The <see cref="TextWriter"/> to write the commands to.</param>
        /// <param name="assembly">The assembly that contains the shell commands.</param>
        /// <exception cref="ArgumentNullException">
        ///   <paramref name="writer"/> or <paramref name="assembly"/> is <see langword="null"/>.
        /// </exception>
        /// <remarks>
        /// <para>
        ///   This method writes a list of all shell command names and their descriptions to <paramref name="writer"/>.
        /// </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>
        ///   If <paramref name="writer"/> is an instance of the <see cref="LineWrappingTextWriter"/> class, the <see cref="LineWrappingTextWriter.Indent"/>
        ///   property will be set to a value appropriate for the formatting of the command list, and indenting will be reset before each command. Indenting
        ///   will not be used if the <see cref="LineWrappingTextWriter.MaximumLineLength"/> is less than 30.
        /// </para>
        /// </remarks>
        public static void WriteAssemblyCommandList(TextWriter writer, Assembly assembly)
        {
            LineWrappingTextWriter lineWriter = writer as LineWrappingTextWriter;

            if (lineWriter != null)
            {
                lineWriter.Indent = lineWriter.MaximumLineLength < CommandLineParser.MaximumLineWidthForIndent ? 0 : 16;
            }

            WriteAssemblyCommandList(writer, assembly, Properties.Resources.DefaultCommandFormat);
        }
コード例 #4
0
        private static void WriteShellCommandListUsage(TextWriter output, Assembly assembly, CreateShellCommandOptions options)
        {
            output.WriteLine(options.CommandUsageFormat, options.UsageOptions.UsagePrefix);
            output.WriteLine();
            output.WriteLine(options.AvailableCommandsHeader);
            output.WriteLine();
            LineWrappingTextWriter lineWriter = output as LineWrappingTextWriter;

            if (lineWriter != null)
            {
                lineWriter.Indent = lineWriter.MaximumLineLength < CommandLineParser.MaximumLineWidthForIndent ? 0 : options.CommandDescriptionIndent;
            }
            WriteAssemblyCommandList(output, assembly, options.CommandDescriptionFormat);
        }
コード例 #5
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();
                }
            }
        }