在构建接受参数的控制台应用程序时,可以使用传递给Main的参数(string[] args)。

在过去,我只是简单地索引/循环该数组,并做了一些正则表达式来提取值。然而,当命令变得更加复杂时,解析就会变得非常糟糕。

我感兴趣的是:

你使用的库 你使用的模式

假设命令总是遵循常见的标准,比如这里回答的。


当前回答

看起来每个人都有自己的宠物命令行解析器,我最好也添加我的:)。

http://bizark.codeplex.com/

这个库包含一个命令行解析器,它将使用命令行中的值初始化一个类。它有很多功能(我已经建立了很多年了)。

从文档中…

怪诞框架中的命令行解析具有以下关键特性:

Automatic initialization: Class properties are automatically set based on the command-line arguments. Default properties: Send in a value without specifying the property name. Value conversion: Uses the powerful ConvertEx class also included in BizArk to convert values to the proper type. Boolean flags: Flags can be specified by simply using the argument (ex, /b for true and /b- for false) or by adding the value true/false, yes/no, etc. Argument arrays: Simply add multiple values after the command-line name to set a property that is defined as an array. Ex, /x 1 2 3 will populate x with the array { 1, 2, 3 } (assuming x is defined as an array of integers). Command-line aliases: A property can support multiple command-line aliases for it. For example, Help uses the alias ?. Partial name recognition: You don’t need to spell out the full name or alias, just spell enough for the parser to disambiguate the property/alias from the others. Supports ClickOnce: Can initialize properties even when they are specified as the query string in a URL for ClickOnce deployed applications. The command-line initialization method will detect if it is running as ClickOnce or not so your code doesn’t need to change when using it. Automatically creates /? help: This includes nice formatting that takes into account the width of the console. Load/Save command-line arguments to a file: This is especially useful if you have multiple large, complex sets of command-line arguments that you want to run multiple times.

其他回答

我个人最喜欢的是Peter palota的http://www.codeproject.com/KB/recipes/plossum_commandline.aspx:

[CommandLineManager(ApplicationName="Hello World",
    Copyright="Copyright (c) Peter Palotas")]
class Options
{
   [CommandLineOption(Description="Displays this help text")]
   public bool Help = false;

   [CommandLineOption(Description = "Specifies the input file", MinOccurs=1)]
   public string Name
   {
      get { return mName; }
      set
      {
         if (String.IsNullOrEmpty(value))
            throw new InvalidOptionValueException(
                "The name must not be empty", false);
         mName = value;
      }
   }

   private string mName;
}

这个问题有很多解决方案。为了完整性和提供替代方案,如果有人需要,我在我的谷歌代码库中添加了两个有用的类的答案。

第一个是ArgumentList,它只负责解析命令行参数。它收集由开关'/x:y'或'-x=y'定义的名值对,还收集'未命名'条目列表。它的基本用法在这里讨论,查看类在这里。

第二部分是CommandInterpreter,它从. net类中创建一个功能齐全的命令行应用程序。举个例子:

using CSharpTest.Net.Commands;
static class Program
{
    static void Main(string[] args)
    {
        new CommandInterpreter(new Commands()).Run(args);
    }
    //example ‘Commands’ class:
    class Commands
    {
        public int SomeValue { get; set; }
        public void DoSomething(string svalue, int ivalue)
        { ... }

使用上面的示例代码,您可以运行以下代码:

exe DoSomething“字符串值

——或——

Program.exe dosomething /ivalue=5 -svalue:"字符串值"

它就是这么简单,也有你想要的那么复杂。您可以查看源代码、查看帮助或下载二进制文件。

我以前写过一个c#命令行参数解析器。网址:http://www.codeplex.com/CommandLineArguments

我最近遇到了FubuCore命令行解析实现,我真的很喜欢它,原因是:

it's easy to use - although I couldn't find a documentation for it, the FubuCore solution also provides a project containing a nice set of Unit Tests that speak more about the functionality than any documentation could it has a nice object oriented design, no code repetition or other such things that I used to have in my command line parsing apps it's declarative: you basically write classes for the Commands and sets of parameters and decorate them with attributes to set various options (e.g. name, description, mandatory/optional) the library even prints a nice Usage Graph, based on these definitions

下面是一个简单的例子说明如何使用它。为了说明用法,我写了一个简单的实用程序,它有两个命令: - add(将一个对象添加到列表中-一个对象由一个名称(字符串),值(int)和一个布尔标志组成) - list(列出当前添加的所有对象)

首先,我为'add'命令写了一个Command类:

[Usage("add", "Adds an object to the list")]
[CommandDescription("Add object", Name = "add")]
public class AddCommand : FubuCommand<CommandInput>
{
    public override bool Execute(CommandInput input)
    {
        State.Objects.Add(input); // add the new object to an in-memory collection

        return true;
    }
}

这个命令接受一个commandput实例作为参数,所以我下面定义它:

public class CommandInput
{
    [RequiredUsage("add"), Description("The name of the object to add")]
    public string ObjectName { get; set; }

    [ValidUsage("add")]
    [Description("The value of the object to add")]
    public int ObjectValue { get; set; }

    [Description("Multiply the value by -1")]
    [ValidUsage("add")]
    [FlagAlias("nv")]
    public bool NegateValueFlag { get; set; }
}

下一个命令是'list',实现如下:

[Usage("list", "List the objects we have so far")]
[CommandDescription("List objects", Name = "list")]
public class ListCommand : FubuCommand<NullInput>
{
    public override bool Execute(NullInput input)
    {
        State.Objects.ForEach(Console.WriteLine);

        return false;
    }
}

'list'命令不带参数,所以我定义了一个NullInput类:

public class NullInput { }

现在剩下的就是在Main()方法中把它连接起来,就像这样:

    static void Main(string[] args)
    {
        var factory = new CommandFactory();
        factory.RegisterCommands(typeof(Program).Assembly);

        var executor = new CommandExecutor(factory);

        executor.Execute(args);
    }

程序按预期工作,在任何命令无效的情况下打印正确用法的提示:

  ------------------------
    Available commands:
  ------------------------
     add -> Add object
    list -> List objects
  ------------------------

下面是'add'命令的用法示例:

Usages for 'add' (Add object)
  add <objectname> [-nv]

  -------------------------------------------------
    Arguments
  -------------------------------------------------
     objectname -> The name of the object to add
    objectvalue -> The value of the object to add
  -------------------------------------------------

  -------------------------------------
    Flags
  -------------------------------------
    [-nv] -> Multiply the value by -1
  -------------------------------------

Genghis命令行解析器可能有点过时,但它的功能非常完整,对我来说工作得很好。