731

パラメータを取るコンソール アプリケーションを構築する場合、 に渡された引数を使用できますMain(string[] args)

過去に、その配列にインデックスを付けたりループしたりして、値を抽出するためにいくつかの正規表現を実行しました。ただし、コマンドが複雑になると、解析が非常に難しくなる可能性があります。

だから私は興味があります:

  • 使用するライブラリ
  • 使用するパターン

コマンドは、 answer hereなどの一般的な標準に常に準拠していると仮定します。

4

20 に答える 20

324

NDesk.Options ( Documentation ) および/またはMono.Options (同じ API、異なる名前空間)を使用することを強くお勧めします。ドキュメントの例:

bool show_help = false;
List<string> names = new List<string> ();
int repeat = 1;

var p = new OptionSet () {
    { "n|name=", "the {NAME} of someone to greet.",
       v => names.Add (v) },
    { "r|repeat=", 
       "the number of {TIMES} to repeat the greeting.\n" + 
          "this must be an integer.",
        (int v) => repeat = v },
    { "v", "increase debug message verbosity",
       v => { if (v != null) ++verbosity; } },
    { "h|help",  "show this message and exit", 
       v => show_help = v != null },
};

List<string> extra;
try {
    extra = p.Parse (args);
}
catch (OptionException e) {
    Console.Write ("greet: ");
    Console.WriteLine (e.Message);
    Console.WriteLine ("Try `greet --help' for more information.");
    return;
}
于 2010-01-14T22:06:25.820 に答える
197

コマンド ライン パーサー ライブラリ ( http://commandline.codeplex.com/ )がとても気に入っています。属性を介してパラメーターを設定する非常にシンプルでエレガントな方法があります。

class Options
{
    [Option("i", "input", Required = true, HelpText = "Input file to read.")]
    public string InputFile { get; set; }

    [Option(null, "length", HelpText = "The maximum number of bytes to process.")]
    public int MaximumLenght { get; set; }

    [Option("v", null, HelpText = "Print details during execution.")]
    public bool Verbose { get; set; }

    [HelpOption(HelpText = "Display this help screen.")]
    public string GetUsage()
    {
        var usage = new StringBuilder();
        usage.AppendLine("Quickstart Application 1.0");
        usage.AppendLine("Read user manual for usage instructions...");
        return usage.ToString();
    }
}
于 2011-09-07T07:29:53.247 に答える
50

WPF TestApiライブラリには、C#開発用の最も優れたコマンドラインパーサーの1つが付属しています。APIに関するIvoManolovのブログから、それを調べることを強くお勧めします。

// EXAMPLE #2:
// Sample for parsing the following command-line:
// Test.exe /verbose /runId=10
// This sample declares a class in which the strongly-
// typed arguments are populated
public class CommandLineArguments
{
   bool? Verbose { get; set; }
   int? RunId { get; set; }
}

CommandLineArguments a = new CommandLineArguments();
CommandLineParser.ParseArguments(args, a);
于 2009-01-29T14:12:55.900 に答える
24

http://github.com/mono/mono/tree/master/mcs/class/Mono.Options/を見てください。

于 2009-01-29T13:40:58.537 に答える
14

誰もが独自のペット コマンドライン パーサーを持っているようです。

http://bizark.codeplex.com/

このライブラリには、コマンドラインからの値でクラスを初期化するコマンドライン パーサーが含まれています。たくさんの機能があります (私は何年にもわたって構築してきました)。

ドキュメントから...

BizArk フレームワークのコマンド ライン解析には、次の主要な機能があります。

  • 自動初期化:クラス プロパティは、コマンド ライン引数に基づいて自動的に設定されます。
  • デフォルトのプロパティ:プロパティ名を指定せずに値を送信します。
  • 値の変換: BizArk にも含まれている強力な ConvertEx クラスを使用して、値を適切な型に変換します。
  • ブール値フラグ:フラグは、引数 (例: true の場合は /b、false の場合は /b-) を使用するか、true/false、yes/no などの値を追加することで指定できます。
  • 引数配列:コマンドライン名の後に複数の値を追加するだけで、配列として定義されたプロパティを設定できます。例、/x 1 2 3 は、x に配列 { 1, 2, 3 } を入力します (x が整数の配列として定義されていると仮定します)。
  • コマンド ライン エイリアス:プロパティは、複数のコマンド ライン エイリアスをサポートできます。たとえば、ヘルプはエイリアス ? を使用します。
  • 部分的な名前の認識:完全な名前またはエイリアスを綴る必要はありません。パーサーがプロパティ/エイリアスを他のものから明確にするのに十分なだけ綴ります。
  • ClickOnce のサポート: ClickOnce でデプロイされたアプリケーションの URL でクエリ文字列として指定されている場合でも、プロパティを初期化できます。コマンド ラインの初期化メソッドは、ClickOnce として実行されているかどうかを検出するため、使用時にコードを変更する必要はありません。
  • /? を自動的に作成します。help:これには、コンソールの幅を考慮した適切な書式設定が含まれます。
  • コマンド ライン引数をファイルにロード/保存する:これは、複数回実行するコマンド ライン引数の大規模で複雑なセットが複数ある場合に特に便利です。
于 2010-07-01T01:03:02.100 に答える
13

しばらく前に、C#コマンドライン引数パーサーを作成しました。その場所:http://www.codeplex.com/CommandLineArguments

于 2009-12-15T07:07:43.817 に答える
9

CLAP (コマンド ライン引数パーサー) には使用可能な API があり、ドキュメントも充実しています。パラメータに注釈を付けてメソッドを作成します。 https://github.com/adrianaisemberg/CLAP

于 2012-03-15T15:11:25.787 に答える
5

この問題には多くの解決策があります。完全を期し、誰かが望む場合に代替手段を提供するために、Googleコードライブラリの2つの便利なクラスにこの回答を追加しています。

1 つ目は、コマンド ライン パラメータの解析のみを担当する ArgumentList です。スイッチ「/x:y」または「-x=y」で定義された名前と値のペアを収集し、「名前のない」エントリのリストも収集します。基本的な使用法についてはこちらで説明しています。クラスはこちらでご覧ください。

この 2 番目の部分は、.Net クラスから完全に機能するコマンドライン アプリケーションを作成するCommandInterpreterです。例として:

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)
        { ... }

上記のコード例では、次を実行できます。

Program.exe DoSomething "文字列値" 5

- また -

Program.exe dosomething /ivalue=5 -svalue:"string value"

必要に応じて、シンプルにすることも、複雑にすることもできます。ソース コードを確認したり、ヘルプを表示したり、バイナリをダウンロードしたりできます。

于 2010-05-11T18:25:59.837 に答える
4

あなたは私の1つのRug.Cmdが好きかもしれません

使いやすく拡張可能なコマンドライン引数パーサー。ハンドル:ブール、プラス/マイナス、文字列、文字列リスト、CSV、列挙。

組み込みの「/?」ヘルプモード。

組み込みの「/??」および「/?D」ドキュメントジェネレータモード。

static void Main(string[] args) 
{            
    // create the argument parser
    ArgumentParser parser = new ArgumentParser("ArgumentExample", "Example of argument parsing");

    // create the argument for a string
    StringArgument StringArg = new StringArgument("String", "Example string argument", "This argument demonstrates string arguments");

    // add the argument to the parser 
    parser.Add("/", "String", StringArg);

    // parse arguemnts
    parser.Parse(args);

    // did the parser detect a /? argument 
    if (parser.HelpMode == false) 
    {
        // was the string argument defined 
        if (StringArg.Defined == true)
        {
            // write its value
            RC.WriteLine("String argument was defined");
            RC.WriteLine(StringArg.Value);
        }
    }
}

編集:これは私のプロジェクトであり、そのため、この回答は第三者からの承認と見なされるべきではありません。それは私が書くすべてのコマンドラインベースのプログラムにそれを使用していると言った、それはオープンソースであり、他の人がそれから利益を得るかもしれないことを願っている。

于 2012-01-23T16:55:08.007 に答える
4

必要かどうかに関係なく、引数の「ルールを定義」できるため、私はそれが好きです...

または、Unix を使用している場合は、 GNU Getopt .NETポートが好きかもしれません。

于 2009-01-29T13:43:09.610 に答える
3

http://www.codeplex.com/commonlibrarynetにコマンド ライン引数パーサーがあります。


1. 属性
2. 明示的な呼び出し
3. 複数の引数の単一行または文字列配列を使用して引数を解析できます

次のようなものを処理できます。

- config :Qa - startdate :${今日} - region :'New York' Settings01

使い方はとても簡単です。

于 2009-04-17T21:28:20.723 に答える
2

Powershellコマンドレット。

コマンドレットで指定された属性、検証のサポート、パラメーターセット、パイプライン処理、エラーレポート、ヘルプ、および他のコマンドレットで使用するために返されるすべての.NETオブジェクトに基づいてPowerShellによって実行される解析。

始めるのに役立つと思ったいくつかのリンク:

于 2012-07-07T05:07:43.860 に答える
2

C# CLIは、私が作成した非常に単純なコマンドライン引数解析ライブラリです。それは十分に文書化されており、オープンソースです。

于 2012-08-11T15:02:34.917 に答える
2

私は最近、FubuCore コマンドライン解析の実装に出くわしました。私はそれが本当に気に入っています。その理由は次のとおりです。

  • 使い方は簡単です。ドキュメントは見つかりませんでしたが、FubuCore ソリューションは、どのドキュメントよりも機能について詳しく説明する、優れた単体テストのセットを含むプロジェクトも提供します。
  • オブジェクト指向の優れた設計で、コマンドライン解析アプリで使用していたコードの繰り返しやその他のものはありません
  • 宣言型です。基本的には、コマンドとパラメーターのセットのクラスを作成し、それらを属性で装飾して、さまざまなオプション (名前、説明、必須/オプションなど) を設定します。
  • ライブラリは、これらの定義に基づいて、素敵な使用状況グラフを出力します

以下は、これを使用する方法の簡単な例です。使い方を説明するために、2 つのコマンドを持つ単純なユーティリティを作成しました。現在追加されているすべてのオブジェクト)

まず、「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;
    }
}

このコマンドは CommandInput インスタンスをパラメーターとして受け取るので、次のように定義します。

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
  -------------------------------------
于 2011-06-11T06:50:37.453 に答える
2

私の個人的なお気に入りは、Peter Palotas による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;
}
于 2011-05-12T06:08:45.837 に答える
1

ジンギスコマンドラインパーサー は少し古くなっているかもしれませんが、それは非常に完全な機能であり、私にとってはかなりうまく機能します。

于 2009-08-21T11:07:24.190 に答える
0

apache commons cli API の .net ポートを使用してください。これはうまくいきます。

http://sourceforge.net/projects/dotnetcli/

概念と導入のための元の API

http://commons.apache.org/cli/

于 2011-06-28T09:04:55.870 に答える
0

オープンソース ライブラリCSharpOptParseをお勧めします。コマンド ラインを解析し、ユーザー定義の .NET オブジェクトをコマンド ライン入力でハイドレートします。C# コンソール アプリケーションを作成するときは、常にこのライブラリを使用します。

于 2010-07-23T14:09:11.607 に答える
0

デフォルトの引数をサポートする、コマンド ライン解析用の非常にシンプルで使いやすいアドホック クラス。

class CommandLineArgs
{
    public static CommandLineArgs I
    {
        get
        {
            return m_instance;
        }
    }

    public  string argAsString( string argName )
    {
        if (m_args.ContainsKey(argName)) {
            return m_args[argName];
        }
        else return "";
    }

    public long argAsLong(string argName)
    {
        if (m_args.ContainsKey(argName))
        {
            return Convert.ToInt64(m_args[argName]);
        }
        else return 0;
    }

    public double argAsDouble(string argName)
    {
        if (m_args.ContainsKey(argName))
        {
            return Convert.ToDouble(m_args[argName]);
        }
        else return 0;
    }

    public void parseArgs(string[] args, string defaultArgs )
    {
        m_args = new Dictionary<string, string>();
        parseDefaults(defaultArgs );

        foreach (string arg in args)
        {
            string[] words = arg.Split('=');
            m_args[words[0]] = words[1];
        }
    }

    private void parseDefaults(string defaultArgs )
    {
        if ( defaultArgs == "" ) return;
        string[] args = defaultArgs.Split(';');

        foreach (string arg in args)
        {
            string[] words = arg.Split('=');
            m_args[words[0]] = words[1];
        }
    }

    private Dictionary<string, string> m_args = null;
    static readonly CommandLineArgs m_instance = new CommandLineArgs();
}

class Program
{
    static void Main(string[] args)
    {
        CommandLineArgs.I.parseArgs(args, "myStringArg=defaultVal;someLong=12");
        Console.WriteLine("Arg myStringArg  : '{0}' ", CommandLineArgs.I.argAsString("myStringArg"));
        Console.WriteLine("Arg someLong     : '{0}' ", CommandLineArgs.I.argAsLong("someLong"));
    }
}
于 2011-06-29T12:43:58.510 に答える