Najlepszy sposób na analizowanie argumentów wiersza poleceń w C #? [Zamknięte]


731

Podczas budowania aplikacji konsolowych, które pobierają parametry, można użyć przekazanych argumentów Main(string[] args).

W przeszłości po prostu indeksowałem / zapętlałem tę tablicę i robiłem kilka wyrażeń regularnych, aby wyodrębnić wartości. Jednak gdy polecenia stają się bardziej skomplikowane, analiza może być dość brzydka.

Więc jestem zainteresowany:

  • Biblioteki, których używasz
  • Wzory, których używasz

Załóżmy, że polecenia zawsze są zgodne z powszechnymi standardami, takimi jak odpowiedzi tutaj .


Poprzednia dyskusja, podzielony ciąg zawierający parametry wiersza polecenia na ciąg w c # , może zawierać kilka odpowiedzi.
gimel

1
Cześć, przepraszam, to trochę nie na temat. jednak używam „Ustawień aplikacji”, aby przekazać argument do aplikacji. Uznałem, że jest dość łatwy w użyciu i nie trzeba pisać parsowania argumentów / plików, ani dodatkowej biblioteki. msdn.microsoft.com/en-us/library/aa730869(VS.80).aspx
zadzwoń do mnie Steve

44
@ zadzwoń do mnie Steve: argumenty wiersza poleceń mogą się różnić w zależności od połączenia - jak to zrobić z ustawieniami aplikacji?
reinierpost

Odpowiedzi:


324

Zdecydowanie sugerowałbym użycie NDesk.Options ( Dokumentacja ) i / lub Mono.Options (ten sam API, inna przestrzeń nazw). Przykład z dokumentacji :

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 jest świetny, ale wydaje się, że nie obsługuje aplikacji konsolowych za pomocą więcej niż jednego odrębnego polecenia. Jeśli chcesz, wypróbuj ManyConsole, która opiera się na NDesk. Opcje: nuget.org/List/Packages/ManyConsole
Frank Schwieterman

5
Kiedy mam jedną aplikację z wieloma odrębnymi poleceniami, „warstwuję” OptionSets. Weźmy mdoc ( docs.go-mono.com/index.aspx?link=man%3amdoc%281%29 ), który ma „globalny” OptionSet ( github.com/mono/mono/blob/master/mcs/tools/ mdoc /… ), który deleguje do opcji OptionSet dla poszczególnych poleceń (np. github.com/mono/mono/blob/master/mcs/tools/mdoc/… )
jonp

3
NDesk nie ma dla mnie pracy. Można odczytać argumenty liczb całkowitych, ale nie łańcuchy. Zmienne wciąż otrzymują argumenty (np. „S”, „a” itp.) Zamiast wartości argumentów (np. „ServerName”, „ApplicationName”). Zamiast tego zrezygnował i użył „Biblioteki analizatora składni wiersza poleceń”. Jak dotąd.
Jay

2
@AshleyHenderson Po pierwsze, jest mały i elastyczny. Większość rozwiązań działa tylko z opcjonalnymi nazwanymi argumentami (tzn. Nie można tego zrobić git checkout master) lub ich argumenty nie są elastyczne (tj. Nie obsługują --foo 123= --foo=123= -f 123= -f=123a także -v -h= -vh).
Wernight

1
@FrankSchwieterman, która powinna być własną odpowiedzią. I dzięki za wskazówkę, ManyConsole to prawdziwa gratka, idealnie dla mnie pasuje.
quentin-starin

197

Naprawdę podoba mi się biblioteka parserów wiersza poleceń ( http://commandline.codeplex.com/ ). Ma bardzo prosty i elegancki sposób ustawiania parametrów za pomocą atrybutów:

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
To jest biblioteka, na której też się osiadłem. Piszę aplikacje dla dużej firmy, które muszą być utrzymywane przez wiele lat - ta biblioteka jest ciągle aktualizowana od 2005 roku, wydaje się być popularna, jest pisana przez ludzi aktywnych w społeczności C # i jest licencjonowana w stylu BSD na wszelki wypadek wsparcie znika.
Charles Burns

Polecam to również. Moim jedynym problemem było: Określenie dozwolonej kombinacji argumentów (np. Jeśli argumentacja przeniesienia musiała mieć również argumenty source i dest), może być możliwe zastosowanie atrybutów. Ale może lepiej będzie, jeśli zrobisz to z osobną logiką walidatora argumentów
Lyndon White,

1
Lubię klasę Options. Wygląda na to, że obsługuje nienazwane parametry i podobne flagi --recursive.
Wernight

2
Właśnie go przetestowałem i zaimplementowałem opcję mojej aplikacji w zaledwie kilka minut. Biblioteka jest niezwykle prosta w użyciu.
Trismegistos,

3
Dla mnie ta biblioteka jest bardzo restrykcyjna. Jeśli potrzebujesz zestawów wyłącznych, nie możesz zdefiniować wymaganych opcji dla każdego zestawu, więc musisz je sprawdzić ręcznie. Nie można zdefiniować minimalnego wymagania dla nienazwanych wartości, należy je również sprawdzić ręcznie. Kreator ekranu pomocy również wcale nie jest elastyczny. Jeśli zachowanie biblioteki nie odpowiada twoim potrzebom po wyjęciu z pudełka, nie możesz zrobić nic, aby to zmienić.
Siergiej Kostrukow,

50

Biblioteka WPF TestApi zawiera jeden z najładniejszych parserów wiersza poleceń do programowania w języku C #. Gorąco polecam przyjrzeć się temu, z bloga Ivo Manolova na 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. Analiza wiersza poleceń jest czymś, co naprawdę powinno pochodzić od dostawcy (tj. Microsoft), a nie za pomocą narzędzia innej firmy, nawet jeśli wsparcie dostawcy jest realizowane w sposób kompleksowy.
Joel Coehoorn

2
To powiedziawszy, zaakceptowana odpowiedź (mono) jest następną najlepszą rzeczą.
Joel Coehoorn

6
@Joel, jaka część jest tak ważna, że ​​analiza wiersza poleceń musi pochodzić od dostawcy? Jakie są twoje powody?
greenoldman

3
@marcias: Myślę, że on ma na myśli, że prawdopodobnie powinien był być po wyjęciu z pudełka ... jak wiele rzeczy :)
user7116

Biblioteka jest ogromna! Zawiera o wiele więcej niż potrzebuję ...
Riri

24

2
Opcje
NDesk

2
Dodam kolejny głos na NDesk, działa dobrze, jest nieinwazyjny i dobrze udokumentowany.
Terence

1
Mono.GetOptions jest bardzo stary, NDesk.Options jest znacznie ładniejszy (lub Mono.Options, jeśli wolisz, to ta sama klasa, tutaj: anonsvn.mono-project.com/source/trunk/mcs/class/Mono.Options/... )
Matt Enright,

7
@Adam Oren: moja odpowiedź ma 1 rok i 1 miesiąc! struktura pnia mono została przebudowana. Ten kod jest teraz umieszczony na anonsvn.mono-project.com/viewvc/branches/mono-2-2/mcs/class/…
abatishchev

6
@Tormod: to Mono.GetOptions jest przestarzałe, a nie Mono.Options. Opcje Mono.Options są nadal utrzymywane.
jonp

14

Wygląda na to, że każdy ma swoje własne parsery z wiersza poleceń dla zwierząt domowych. Myślę, że lepiej też dodać moje :).

http://bizark.codeplex.com/

Ta biblioteka zawiera analizator składni wiersza polecenia , który zainicjuje klasę wartościami z wiersza polecenia. Ma mnóstwo funkcji (budowałem go od wielu lat).

Z dokumentacji ...

Analiza wiersza poleceń w środowisku BizArk ma następujące kluczowe funkcje:

  • Automatyczna inicjalizacja: Właściwości klasy są ustawiane automatycznie na podstawie argumentów wiersza poleceń.
  • Właściwości domyślne: Wyślij wartość bez podawania nazwy właściwości.
  • Konwersja wartości: Używa potężnej klasy ConvertEx zawartej również w BizArk do konwersji wartości na odpowiedni typ.
  • Flagi boolowskie: Flagi można określić, po prostu używając argumentu (np. / B dla true i / b- dla false) lub dodając wartość true / false, tak / nie itd.
  • Tablice argumentów: po prostu dodaj wiele wartości po nazwie wiersza polecenia, aby ustawić właściwość zdefiniowaną jako tablica. Np. / X 1 2 3 zapełni x tablicą {1, 2, 3} (zakładając, że x jest zdefiniowane jako tablica liczb całkowitych).
  • Aliasy wiersza polecenia: Właściwość może obsługiwać wiele aliasów wiersza polecenia. Na przykład Pomoc korzysta z aliasu?
  • Częściowe rozpoznawanie nazw: Nie musisz przeliterować pełnej nazwy lub aliasu, wystarczy przeliterować wystarczająco, aby parser mógł ujednoznacznić właściwość / alias od innych.
  • Obsługuje ClickOnce: może inicjować właściwości, nawet jeśli są one określone jako ciąg zapytania w adresie URL dla wdrożonych aplikacji ClickOnce. Metoda inicjowania wiersza polecenia wykryje, czy działa jako ClickOnce, czy nie, więc kod nie musi się zmieniać podczas korzystania z niego.
  • Automatycznie tworzy /? pomoc: obejmuje ładne formatowanie, które uwzględnia szerokość konsoli.
  • Załaduj / Zapisz argumenty wiersza polecenia do pliku: Jest to szczególnie przydatne, jeśli masz wiele dużych, złożonych zestawów argumentów wiersza polecenia, które chcesz uruchamiać wiele razy.

2
Odkryłem, że parser linii poleceń BizArk jest znacznie łatwiejszy i płynniejszy niż inne. Wysoce polecany!
Boris Modylevsky,


9

CLAP (parser argumentów wiersza poleceń) ma użyteczny interfejs API i jest doskonale udokumentowany. Tworzysz metodę z adnotacjami parametrów. https://github.com/adrianaisemberg/CLAP


2
Jest bardzo prosty w użyciu, a ich strona internetowa działa. Ich składnia nie jest jednak zbyt intuicyjna: myapp myverb -argname argvalue(musi mieć -argname) lub myapp -help(zwykle --help).
Wernight

@Wernight możesz użyć parametru IsDefault na Czasowniku, aby można go było pominąć. Nie znalazłem wsparcia dla parametrów pozycyjnych, ale użyłem parametrów pozycyjnych tylko podczas samodzielnej analizy linii poleceń. O wiele łatwiej jest używać nazwanych argumentów, po których następują wartości IMHO.
Loudenvier,

5

Istnieje wiele rozwiązań tego problemu. Dla kompletności i dla zapewnienia alternatywy, jeśli ktoś chce, dodam tę odpowiedź dla dwóch przydatnych klas w mojej bibliotece kodów Google .

Pierwszy to ArgumentList, który jest odpowiedzialny tylko za analizowanie parametrów wiersza poleceń. Zbiera pary nazwa-wartość zdefiniowane przełącznikami „/ x: y” lub „-x = y”, a także zbiera listę „nienazwanych” wpisów. Omówiono tutaj podstawowe użycie , zobacz klasę tutaj .

Drugą częścią tego jest CommandInterpreter, który tworzy w pełni funkcjonalną aplikację z linii poleceń z twojej klasy .Net. Jako przykład:

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

Za pomocą powyższego przykładowego kodu można uruchomić następujące czynności:

Program.exe DoSomething „wartość ciągu” 5

- lub -

Program.exe dosomething / ivalue = 5-wartość: „wartość ciągu”

To takie proste lub tak skomplikowane, jak potrzebujesz. Możesz przejrzeć kod źródłowy , przejrzeć pomoc lub pobrać plik binarny .



4

Możesz polubić mój jeden dywanik

Łatwy w użyciu i rozwijany analizator argumentów wiersza poleceń. Uchwyty: Bool, Plus / Minus, ciąg, lista ciągów, CSV, wyliczanie.

Wbudowany w „/?” tryb pomocy.

Wbudowany w „/ ??” oraz tryby generatora dokumentów „/? 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);
        }
    }
}

Edycja: To jest mój projekt i jako taka odpowiedź nie powinna być postrzegana jako aprobata strony trzeciej. To powiedziawszy, używam go do każdego napisanego przeze mnie programu opartego na linii poleceń, jest to oprogramowanie typu open source i mam nadzieję, że inni mogą z niego skorzystać.


Tylko do Twojej wiadomości, że powinieneś umieścić małe zastrzeżenie, że jesteś powiązany z projektem Rug.Cmd (jak wspomniano w FAQ): stackoverflow.com/faq#promotion - Nie jest to wielka sprawa, ponieważ promujesz otwarte- projekt źródłowy, ale dobrze jest dodać zastrzeżenie;) Nawiasem mówiąc, +1 ... wygląda całkiem dobrze.
Jason Down

Pozdrawiam za zwrócenie na to uwagi i dziękuję za +1, upewnię się, że wyrażam się jasno o mojej przynależności.
Phill Tew

Nie martw się ... istnieją pewne dziwactwa dla tego typu rzeczy (nie jestem jednym z nich), więc lubię dawać ludziom głowy. Znów nie jest to zwykle problem w przypadku projektów typu open source. Ma to przede wszystkim na celu powstrzymanie ludzi przed spamowaniem rekomendacji dotyczących ich (płatnych) produktów.
Jason Down

3

Parser argumentów wiersza poleceń znajduje się na stronie http://www.codeplex.com/commonlibrarynet

Może analizować argumenty za pomocą
1. atrybutów
2. jawnych wywołań
3. pojedynczej linii wielu argumentów LUB tablicy ciągów

Może obsługiwać takie rzeczy jak:

- config : Qa - data rozpoczęcia : $ { dzisiaj } - region : Ustawienia „Nowy Jork” 01

Jest bardzo łatwy w użyciu.


2

To jest program obsługi, który napisałem na podstawie Optionsklasy Novell .

Ta jest skierowana do aplikacji konsolowych, które wykonują while (input !="exit")pętlę stylu, konsoli interaktywnej, takiej jak na przykład konsola FTP.

Przykładowe użycie:

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

I źródło:

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

Moim ulubionym jest http://www.codeproject.com/KB/recipes/plossum_commandline.aspx autorstwa Petera Palotasa:

[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

Ostatnio natknąłem się na implementację parsowania wiersza poleceń FubuCore. Bardzo mi się podoba, ponieważ:

  • jest łatwy w użyciu - chociaż nie mogłem znaleźć dokumentacji na jego temat, rozwiązanie FubuCore zapewnia również projekt zawierający ładny zestaw testów jednostkowych, które mówią więcej o funkcjonalności niż jakakolwiek dokumentacja
  • ma ładny obiektowy design, bez powtarzania kodu lub innych podobnych rzeczy, które miałem w mojej aplikacji do analizowania wiersza poleceń
  • jest deklaratywny: w zasadzie piszesz klasy dla poleceń i zestawów parametrów i dekorujesz je atrybutami, aby ustawić różne opcje (np. nazwa, opis, obowiązkowe / opcjonalne)
  • biblioteka drukuje nawet ładny wykres użytkowania na podstawie tych definicji

Poniżej znajduje się prosty przykład, jak z tego korzystać. Aby zilustrować użycie, napisałem proste narzędzie, które ma dwa polecenia: - dodaj (dodaje obiekt do listy - obiekt składa się z nazwy (łańcucha), wartości (int) i flagi boolowskiej) - listy (list wszystkie aktualnie dodane obiekty)

Przede wszystkim napisałem klasę Command dla polecenia „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;
    }
}

To polecenie przyjmuje instancję CommandInput jako parametr, więc definiuję następną:

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

Następnym poleceniem jest „lista”, które jest realizowane w następujący sposób:

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

Polecenie „list” nie przyjmuje parametrów, więc zdefiniowałem dla tego klasę NullInput:

public class NullInput { }

Teraz pozostaje tylko załączyć to w metodzie Main (), tak jak to:

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

        var executor = new CommandExecutor(factory);

        executor.Execute(args);
    }

Program działa zgodnie z oczekiwaniami, drukując wskazówki dotyczące prawidłowego użycia w przypadku, gdy jakiekolwiek polecenia są nieprawidłowe:

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

I przykładowe użycie polecenia „dodaj”:

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

C # CLI to bardzo prosta biblioteka do analizy argumentów wiersza poleceń, którą napisałem. To dobrze udokumentowane i otwarte oprogramowanie.


Dobrze udokumentowane? Gdzie jest dokumentacja?
Suhas,

Istnieje dokumentacja wewnętrzna (tj. W bazie kodu), a także dokumentacja zewnętrzna (patrz Readme.mkdplik w Documentationfolderze).
Bernard,

Ok, skomentowałem pośpiesznie. Być może możesz przenieść projekt do github, a twoja dokumentacja automatycznie zacznie pojawiać się na stronie głównej.
Suhas


0

Sugerowałbym bibliotekę open source CSharpOptParse . Analizuje wiersz poleceń i nawadnia zdefiniowany przez użytkownika obiekt .NET za pomocą danych wejściowych wiersza polecenia. Zawsze zwracam się do tej biblioteki podczas pisania aplikacji konsoli C #.



0

Bardzo prosta i łatwa w użyciu klasa ad hoc do analizowania wiersza poleceń, która obsługuje domyślne argumenty.

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"));
    }
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.