Cách tốt nhất để phân tích các đối số dòng lệnh trong C #? [đóng cửa]


731

Khi xây dựng các ứng dụng bảng điều khiển lấy tham số, bạn có thể sử dụng các đối số được truyền vào Main(string[] args).

Trước đây, tôi chỉ đơn giản là lập chỉ mục / lặp lại mảng đó và thực hiện một vài biểu thức chính quy để trích xuất các giá trị. Tuy nhiên, khi các lệnh trở nên phức tạp hơn, việc phân tích cú pháp có thể trở nên khá xấu xí.

Vì vậy, tôi quan tâm đến:

  • Thư viện mà bạn sử dụng
  • Các mẫu mà bạn sử dụng

Giả sử các lệnh luôn tuân thủ các tiêu chuẩn chung như được trả lời ở đây .


Một cuộc thảo luận trước đó, split-string-chứa-lệnh-line-tham số-thành-chuỗi-in-c # , có thể có một số câu trả lời.
gimel

1
Xin chào, xin lỗi, nó hơi lạc đề. tuy nhiên tôi sử dụng "Cài đặt ứng dụng" để truyền đối số cho ứng dụng. Tôi thấy nó khá dễ sử dụng và không cần phải viết phân tích đối số / tệp và không cần thêm thư viện. msdn.microsoft.com/en-us/l Library / aa730869 (VS.80) .aspx
hãy gọi cho tôi Steve

44
@ gọi cho tôi Steve: điểm của các đối số dòng lệnh là chúng có thể thay đổi theo mỗi cuộc gọi - làm thế nào để bạn làm điều đó với các cài đặt ứng dụng?
Revierpost

Câu trả lời:


324

Tôi thực sự khuyên bạn nên sử dụng NDesk.Options ( Tài liệu ) và / hoặc Mono.Options (cùng API, không gian tên khác nhau). Một ví dụ từ tài liệu :

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;
}

14
NDesk.options là tuyệt vời, nhưng dường như không thực sự hỗ trợ các ứng dụng bảng điều khiển với nhiều hơn một lệnh riêng biệt. Nếu bạn muốn điều đó, hãy thử ManyConsole xây dựng trên NDesk.Options: nuget.org/List/Packages/ManyConsole
Frank Schwieterman

5
Khi tôi có một ứng dụng có nhiều lệnh riêng biệt, tôi "lớp" các OptionSets. Hãy dùng mdoc ( docs.go-mono.com/index.aspx?link=man%3amdoc%281%29 ), có tùy chọn "toàn cầu" ( github.com/mono/mono/blob/master/mcs/tools/ mdoc / xoa ) mà ủy nhiệm cho một Tùy chọn cho mỗi lệnh (ví dụ: github.com/mono/mono/blob/master/mcs/tools/mdoc/ọ )
jonp

3
NDesk không làm việc cho tôi. Có thể đọc đối số nguyên ok nhưng không phải chuỗi. Các biến tiếp tục nhận được các đối số (ví dụ: 's', 'a', v.v.) thay vì các giá trị đối số (ví dụ: 'serverName', 'ApplicationName'). Thay vào đó và sử dụng 'Thư viện phân tích cú pháp dòng lệnh'. Ok cho đến nay.
Jay

2
@AshleyHenderson Đối với một điều, nó nhỏ và linh hoạt. Hầu hết các giải pháp chỉ hoạt động với các đối số có tên tùy chọn (nghĩa là không thể thực hiện git checkout master) hoặc các đối số của chúng không linh hoạt (nghĩa là không hỗ trợ --foo 123= --foo=123= -f 123= -f=123và cũng -v -h= -vh).
Wernight

1
@FrankSchwieterman nên là câu trả lời của riêng nó. Và cảm ơn vì tiền boa, ManyConsole là một món ăn thực sự, hoàn toàn phù hợp với tôi.
quentin-starin

197

Tôi thực sự thích Thư viện phân tích dòng lệnh ( http://commandline.codeplex.com/ ). Nó có một cách rất đơn giản và thanh lịch để thiết lập các tham số thông qua các thuộc tính:

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();
    }
}

6
Đây là thư viện mà tôi đã giải quyết là tốt. Tôi đang viết đơn cho một công ty lớn cần được duy trì trong nhiều năm - thư viện này đã được cập nhật liên tục từ năm 2005, dường như rất phổ biến, được viết bởi những người hoạt động trong cộng đồng C # và được cấp phép theo kiểu BSD trong trường hợp hỗ trợ không biến mất.
Charles Burns

Tôi cũng đề nghị điều này. Vấn đề duy nhất của tôi là: Chỉ định kết hợp tranh luận được phép (Ví dụ: nếu tranh luận di chuyển phải có nguồn và đối số mệnh cũng có thể được thực hiện với các thuộc tính. Nhưng bạn có thể tốt hơn nên làm điều đó với logic trình xác thực đối số riêng biệt
Lyndon White

1
Tôi thích lớp Tùy chọn. Nó dường như hỗ trợ các tham số không tên và cờ như --recursivequá.
Wernight

2
Tôi vừa thử nghiệm nó và tôi đã thực hiện tùy chọn cho ứng dụng của mình chỉ trong vài phút. Nó là cực kỳ đơn giản để sử dụng thư viện.
Trismegistos

3
Tôi thấy thư viện này rất hạn chế cho bản thân mình. Nếu bạn cần các bộ độc quyền, bạn không thể xác định các tùy chọn bắt buộc cho mỗi bộ, do đó phải kiểm tra chúng theo cách thủ công. Bạn không thể xác định yêu cầu tối thiểu cho các giá trị không tên, bạn cũng phải kiểm tra chúng theo cách thủ công. Trợ giúp xây dựng màn hình cũng không linh hoạt chút nào. Nếu hành vi của thư viện không phù hợp với nhu cầu của bạn, bạn hầu như không thể thay đổi nó.
Sergey Kostrukov

50

Các thư viện WPF TestApi đi kèm với một trong những phân tích cú pháp dòng lệnh đẹp nhất cho C phát triển #. Tôi thực sự khuyên bạn nên xem xét nó, từ blog của Ivo Manolov về API :

// 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);

19
+1. Phân tích cú pháp dòng lệnh là thứ thực sự nên đến từ nhà cung cấp (tức là Microsoft) thay vì thông qua công cụ của bên thứ 3, ngay cả khi sự hỗ trợ của nhà cung cấp đi theo cách thức xoay quanh.
Joel Coehoorn

2
Điều đó nói rằng, câu trả lời được chấp nhận (mono) là điều tốt nhất tiếp theo.
Joel Coehoorn

6
@Joel, phần nào quan trọng mà phân tích dòng lệnh phải từ nhà cung cấp? Lý do của bạn là gì?
greenoldman

3
@marcias: Tôi nghĩ rằng anh ấy có lẽ nên ra khỏi Hộp ... giống như rất nhiều thứ :)
user7116

Thư viện rất lớn! Chứa nhiều hơn tôi cần ...
Riri

24

2
Các tùy chọn NDesk có API rất đẹp
user35149

2
Tôi sẽ thêm một phiếu bầu khác cho NDesk, nó hoạt động tốt, không xâm phạm và được ghi chép tốt.
Terence

1
Mono.GetOptions rất cũ, NDesk.Options đẹp hơn nhiều (hoặc Mono.Options nếu bạn thích, cùng một lớp, ở đây: anonsvn.mono-project.com/source/trunk/mcs/ class / Mono.Options / )
Matt Enright

7
@Adam Oren: câu trả lời của tôi là 1 tuổi 1 tháng! cấu trúc thân cây mono đã được tái cấu trúc. Mã đó hiện được đặt vào anonsvn.mono-project.com/viewvc/branches/mono-2-2/mcs/ class / giả
abatishchev

6
@Tormod: đó là Mono.GetOptions đã lỗi thời, không phải Mono.Options. Mono.Options vẫn được duy trì.
jonp

14

Có vẻ như tất cả mọi người đều có trình phân tích cú pháp dòng lệnh thú cưng của riêng họ, hình tôi cũng đã thêm tốt hơn của tôi :).

http://bizark.codeplex.com/

Thư viện này chứa một trình phân tích cú pháp dòng lệnh sẽ khởi tạo một lớp với các giá trị từ dòng lệnh. Nó có rất nhiều tính năng (tôi đã xây dựng nó trong nhiều năm).

Từ tài liệu ...

Phân tích cú pháp dòng lệnh trong khung BizArk có các tính năng chính sau:

  • Tự động khởi tạo: Các thuộc tính lớp được tự động thiết lập dựa trên các đối số dòng lệnh.
  • Thuộc tính mặc định: Gửi trong một giá trị mà không chỉ định tên thuộc tính.
  • Chuyển đổi giá trị: Sử dụng lớp ConvertEx mạnh mẽ cũng được bao gồm trong BizArk để chuyển đổi giá trị thành loại thích hợp.
  • Cờ Boolean: Cờ có thể được chỉ định bằng cách sử dụng đối số (ex, / b cho true và / b- cho false) hoặc bằng cách thêm giá trị true / false, yes / no, v.v.
  • Mảng đối số: Đơn giản chỉ cần thêm nhiều giá trị sau tên dòng lệnh để đặt thuộc tính được xác định là một mảng. Ex, / x 1 2 3 sẽ điền x với mảng {1, 2, 3} (giả sử x được định nghĩa là một mảng các số nguyên).
  • Bí danh dòng lệnh: Một thuộc tính có thể hỗ trợ nhiều bí danh dòng lệnh cho nó. Ví dụ: Trợ giúp sử dụng bí danh?
  • Nhận dạng tên một phần: Bạn không cần phải đánh vần tên đầy đủ hoặc bí danh, chỉ cần đánh vần đủ để trình phân tích cú pháp phân biệt tài sản / bí danh từ những người khác.
  • Hỗ trợ ClickOnce: Có thể khởi tạo các thuộc tính ngay cả khi chúng được chỉ định làm chuỗi truy vấn trong URL cho các ứng dụng được triển khai ClickOnce. Phương thức khởi tạo dòng lệnh sẽ phát hiện xem nó có chạy như ClickOnce hay không để mã của bạn không cần thay đổi khi sử dụng.
  • Tự động tạo /? help: Điều này bao gồm định dạng đẹp có tính đến chiều rộng của giao diện điều khiển.
  • Tải / Lưu đối số dòng lệnh vào một tệp: Điều này đặc biệt hữu ích nếu bạn có nhiều bộ đối số dòng lệnh lớn, phức tạp mà bạn muốn chạy nhiều lần.

2
Tôi thấy trình phân tích cú pháp dòng lệnh của BizArk dễ dàng và trôi chảy hơn nhiều so với các trình phân tích khác. Rất khuyến khích!
Boris Modylevsky


9

CLAP (trình phân tích đối số dòng lệnh) có API có thể sử dụng và được ghi lại một cách tuyệt vời. Bạn thực hiện một phương thức, chú thích các tham số. https://github.com/adrianaisprice/CLAP


2
Nó rất đơn giản để sử dụng và đá trang web của họ. Cú pháp của họ tuy nhiên không trực quan lắm: myapp myverb -argname argvalue(phải có -argname) hoặc myapp -help(thông thường --help).
Wernight

@Wernight bạn có thể sử dụng tham số IsDefault trên Verb để có thể bỏ qua nó. Tôi không tìm thấy sự hỗ trợ cho các tham số vị trí, nhưng tôi chỉ sử dụng các tham số vị trí khi tôi tự phân tích cú pháp dòng lệnh. Rõ ràng hơn nhiều khi sử dụng các đối số được đặt tên theo sau là các giá trị IMHO.
Lâu đài

5

Có rất nhiều giải pháp cho vấn đề này. Để hoàn thiện và cung cấp giải pháp thay thế nếu ai đó mong muốn tôi sẽ thêm câu trả lời này cho hai lớp hữu ích trong thư viện mã google của tôi .

Đầu tiên là ArgumentList chỉ chịu trách nhiệm phân tích các tham số dòng lệnh. Nó thu thập các cặp giá trị tên được xác định bởi các công tắc '/ x: y' hoặc '-x = y' và cũng thu thập danh sách các mục nhập 'không tên'. Cách sử dụng cơ bản được thảo luận ở đây , xem lớp ở đây .

Phần thứ hai của điều này là CommandInterpreter tạo ra một ứng dụng dòng lệnh đầy đủ chức năng từ lớp .Net của bạn. Ví dụ:

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

Với mã ví dụ trên, bạn có thể chạy như sau:

Program.exe DoS Something "chuỗi giá trị" 5

-- hoặc là --

Program.exe dos Something / ivalue = 5 -svalue: "chuỗi giá trị"

Nó đơn giản như vậy hoặc phức tạp như bạn cần. Bạn có thể xem lại mã nguồn , xem trợ giúp hoặc tải xuống tệp nhị phân .


4

Tôi thích cái đó , vì bạn có thể "xác định quy tắc" cho các đối số, cần hay không, ...

hoặc nếu bạn là một người Unix, hơn bạn có thể thích cổng GNU Getopt .NET .


4

Bạn có thể thích một Rug.Cmd của tôi

Dễ sử dụng và có thể mở rộng trình phân tích cú pháp đối số dòng lệnh. Xử lý: Bool, Plus / Minus, String, String List, CSV, Enumutions.

Được xây dựng trong '/?' chế độ trợ giúp.

Được xây dựng trong '/??' và chế độ tạo tài liệu '/? 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);
        }
    }
}

Chỉnh sửa: Đây là dự án của tôi và vì vậy câu trả lời này không nên được xem là sự chứng thực từ bên thứ ba. Điều đó nói rằng tôi sử dụng nó cho mọi chương trình dựa trên dòng lệnh tôi viết, nó là nguồn mở và tôi hy vọng rằng những người khác có thể được hưởng lợi từ nó.


Chỉ là một FYI, bạn nên từ chối một chút từ chối rằng bạn có liên kết với dự án Rug.Cmd (như được đề cập trong Câu hỏi thường gặp): stackoverflow.com/faq#promotion - Không phải là vấn đề lớn vì bạn đang quảng cáo mở dự án nguồn, nhưng vẫn tốt khi thêm từ chối trách nhiệm;) +1 bằng cách này ... có vẻ được thực hiện khá tốt.
Jason Xuống

Chúc mừng vì đã chỉ ra và cảm ơn về +1, tôi sẽ đảm bảo rằng tôi rõ ràng hơn về liên kết của mình.
Phill Tew

Đừng lo lắng ... có một số người mắc kẹt ngoài kia cho loại điều này (tôi không phải là một trong số họ), vì vậy tôi muốn cho mọi người ngẩng cao đầu. Một lần nữa, thường không phải là một vấn đề cho các dự án nguồn mở. Chủ yếu là để ngăn mọi người khỏi các đề xuất spam cho các sản phẩm (trả phí) của họ.
Jason Xuống

3

Có một trình phân tích cú pháp đối số dòng lệnh tại http://www.codeplex.com/commonl Librarynet

Nó có thể phân tích các đối số bằng cách sử dụng
1. các thuộc tính
2. các cuộc gọi rõ ràng
3. một dòng của nhiều đối số HOẶC mảng chuỗi

Nó có thể xử lý những việc như sau:

- config : Qa - startdate : $ { hôm nay } - khu vực : Cài đặt 'New York'

Nó rất dễ sử dụng.


2

Đây là một trình xử lý tôi đã viết dựa trên Optionslớp Novell .

Điều này nhằm vào các ứng dụng bảng điều khiển thực thi một while (input !="exit")vòng lặp kiểu, một bảng điều khiển tương tác, chẳng hạn như bảng điều khiển FTP chẳng hạn.

Ví dụ sử dụng:

static void Main(string[] args)
{
    // Setup
    CommandHandler handler = new CommandHandler();
    CommandOptions options = new CommandOptions();

    // Add some commands. Use the v syntax for passing arguments
    options.Add("show", handler.Show)
        .Add("connect", v => handler.Connect(v))
        .Add("dir", handler.Dir);

    // Read lines
    System.Console.Write(">");
    string input = System.Console.ReadLine();

    while (input != "quit" && input != "exit")
    {
        if (input == "cls" || input == "clear")
        {
            System.Console.Clear();
        }
        else
        {
            if (!string.IsNullOrEmpty(input))
            {
                if (options.Parse(input))
                {
                    System.Console.WriteLine(handler.OutputMessage);
                }
                else
                {
                    System.Console.WriteLine("I didn't understand that command");
                }

            }

        }

        System.Console.Write(">");
        input = System.Console.ReadLine();
    }
}

Và nguồn:

/// <summary>
/// A class for parsing commands inside a tool. Based on Novell Options class (http://www.ndesk.org/Options).
/// </summary>
public class CommandOptions
{
    private Dictionary<string, Action<string[]>> _actions;
    private Dictionary<string, Action> _actionsNoParams;

    /// <summary>
    /// Initializes a new instance of the <see cref="CommandOptions"/> class.
    /// </summary>
    public CommandOptions()
    {
        _actions = new Dictionary<string, Action<string[]>>();
        _actionsNoParams = new Dictionary<string, Action>();
    }

    /// <summary>
    /// Adds a command option and an action to perform when the command is found.
    /// </summary>
    /// <param name="name">The name of the command.</param>
    /// <param name="action">An action delegate</param>
    /// <returns>The current CommandOptions instance.</returns>
    public CommandOptions Add(string name, Action action)
    {
        _actionsNoParams.Add(name, action);
        return this;
    }

    /// <summary>
    /// Adds a command option and an action (with parameter) to perform when the command is found.
    /// </summary>
    /// <param name="name">The name of the command.</param>
    /// <param name="action">An action delegate that has one parameter - string[] args.</param>
    /// <returns>The current CommandOptions instance.</returns>
    public CommandOptions Add(string name, Action<string[]> action)
    {
        _actions.Add(name, action);
        return this;
    }

    /// <summary>
    /// Parses the text command and calls any actions associated with the command.
    /// </summary>
    /// <param name="command">The text command, e.g "show databases"</param>
    public bool Parse(string command)
    {
        if (command.IndexOf(" ") == -1)
        {
            // No params
            foreach (string key in _actionsNoParams.Keys)
            {
                if (command == key)
                {
                    _actionsNoParams[key].Invoke();
                    return true;
                }
            }
        }
        else
        {
            // Params
            foreach (string key in _actions.Keys)
            {
                if (command.StartsWith(key) && command.Length > key.Length)
                {

                    string options = command.Substring(key.Length);
                    options = options.Trim();
                    string[] parts = options.Split(' ');
                    _actions[key].Invoke(parts);
                    return true;
                }
            }
        }

        return false;
    }
}

2

Sở thích cá nhân của tôi là http://www.codeproject.com/KB/recipes/plossum_commandline.aspx của Peter Palotas:

[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;
}

2

Gần đây tôi đã bắt gặp triển khai phân tích cú pháp dòng lệnh FubuCore Tôi thực sự thích nó, lý do là:

  • nó rất dễ sử dụng - mặc dù tôi không thể tìm thấy tài liệu cho nó, giải pháp FubuCore cũng cung cấp một dự án chứa một bộ Bài kiểm tra đơn vị đẹp nói về chức năng hơn bất kỳ tài liệu nào có thể
  • nó có một thiết kế hướng đối tượng đẹp, không lặp lại mã hoặc những thứ khác mà tôi từng có trong các ứng dụng phân tích cú pháp dòng lệnh của mình
  • đó là khai báo: về cơ bản bạn viết các lớp cho các Lệnh và bộ tham số và trang trí chúng bằng các thuộc tính để đặt các tùy chọn khác nhau (ví dụ: tên, mô tả, bắt buộc / tùy chọn)
  • thư viện thậm chí còn in một Biểu đồ sử dụng đẹp, dựa trên các định nghĩa này

Dưới đây là một ví dụ đơn giản về cách sử dụng này. Để minh họa cách sử dụng, tôi đã viết một tiện ích đơn giản có hai lệnh: - add (thêm một đối tượng vào danh sách - một đối tượng bao gồm tên (chuỗi), value (int) và cờ boolean) - list (danh sách tất cả các đối tượng hiện được thêm vào)

Trước hết, tôi đã viết một lớp Command cho lệnh 'add':

[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;
    }
}

Lệnh này lấy một đối tượng CommandInput làm tham số, vì vậy tôi xác định tiếp theo:

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; }
}

Lệnh tiếp theo là 'list', được thực hiện như sau:

[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;
    }
}

Lệnh 'list' không có tham số, vì vậy tôi đã định nghĩa một lớp NullInput cho việc này:

public class NullInput { }

Tất cả những gì còn lại bây giờ là kết nối điều này trong phương thức Main (), như thế này:

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

        var executor = new CommandExecutor(factory);

        executor.Execute(args);
    }

Chương trình hoạt động như mong đợi, in gợi ý về cách sử dụng đúng trong trường hợp bất kỳ lệnh nào không hợp lệ:

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

Và một cách sử dụng mẫu cho lệnh '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
  -------------------------------------

2

Bộ chỉ huy Powershell.

Phân tích cú pháp được thực hiện bởi powershell dựa trên các thuộc tính được chỉ định trên các lệnh, hỗ trợ xác thực, bộ tham số, đường ống, báo cáo lỗi, trợ giúp và tốt nhất trong tất cả các đối tượng .NET trả về để sử dụng trong các lệnh khác.

Một vài liên kết tôi thấy hữu ích khi bắt đầu:


2

C # CLI là một thư viện phân tích cú pháp đối số dòng lệnh rất đơn giản mà tôi đã viết. Đó là tài liệu tốt và nguồn mở.


Tài liệu tốt? Tài liệu ở đâu?
Suhas

Có tài liệu nội bộ (tức là trong cơ sở mã) cũng như tài liệu bên ngoài (xem Readme.mkdtệp trong Documentationthư mục).
Bernard

Ok, tôi bình luận vội vàng. Có thể bạn có thể chuyển dự án của mình sang github và tài liệu của bạn sẽ tự động bắt đầu xuất hiện trên trang chủ.
Suhas


0

Tôi muốn đề xuất thư viện mã nguồn mở CSharpOptPude . Nó phân tích cú pháp dòng lệnh và hydrat hóa một đối tượng .NET do người dùng định nghĩa bằng đầu vào dòng lệnh. Tôi luôn chuyển sang thư viện này khi viết ứng dụng bảng điều khiển C #.



0

Một lớp ad hoc rất đơn giản dễ sử dụng để phân tích cú pháp dòng lệnh, hỗ trợ các đối số mặc định.

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"));
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.