Как проанализировать параметры .exe внутри программы? - PullRequest
4 голосов
/ 27 ноября 2008

У меня есть программа, которая может иметь много параметров (у нас более 30 различных вариантов).

Пример: myProgram.exe -t alpha 1 -prod 1 2 -sleep 200

Это 3 команды (из объекта шаблона команды в конце), каждая из которых содержит некоторые параметры. Внутри кода мы анализируем все команды (начинаются с -) и получаем список строк (разделяем все пространство) для параметров. Таким образом, на самом деле мы имеем: string -> Коллекция параметров String для каждой команды.

На данный момент мы используем сравнение строк, и мы можем заставить все это работать (например, конкретную команду и вернуть интерфейс ICommand). Проблема в том, что нам нужно делать много IF каждый раз, чтобы получить хорошую команду.

Есть ли у вас шаблон, который можно использовать для извлечения всех параметров из EXE без использования большого количества IF?

Код написан на C #, но я думаю, что логикой может быть и любой другой язык ...

Ответы [ 9 ]

6 голосов
/ 27 ноября 2008

(ну, так как это помечено Python):

Мы используем для этой цели модуль Python optparse . У него гораздо более удобный API, чем у многих ifs.

5 голосов
/ 27 ноября 2008

Библиотека полезных опций для C #: NDesk.Options

5 голосов
/ 27 ноября 2008

Создайте хеш-таблицу, в которой хранятся указатели функций (в C #, которые будут делегатами) для обработки каждого из параметров, вводимых с использованием текста параметра. Затем вы просто проходите через командную строку в цикле и делаете вызовы делегатам, основываясь на результатах поиска по хеш-таблице.

4 голосов
/ 27 ноября 2008

Функция getopt очень распространена для программирования на Си. Он может анализировать параметры для вас. Вот вопрос (и ответ), где взять его для C #: Библиотека GetOpt для C # .

Особенно lappies Реализация выглядит как довольно современный C # с атрибутами и тому подобное.

1 голос
/ 27 ноября 2008

Ответ на Java, как это часто бывает, заключается в том, что кто-то избил вас и выпустил отличную библиотеку с открытым исходным кодом для этого. Посмотрите на Apache CLI .

1 голос
/ 27 ноября 2008

Ради интереса вы можете создать оболочку для всего этого и работать со строгими именами в своем коде. Больше работы? Да. Но веселее, и как только вы добавите новую команду в оболочку, вы можете об этом забыть;)

public class Form1 
{ 

private void main() 
{ 
    MyCommandHandler CommandLineHandler = new MyCommandHandler(); 
    CommandLineHandler.SetInput = "-t alpha 1 -prod 1 2 -sleep 200"; 

    //now we can use strong name to work with the variables: 
    //CommandLineHandler.prod.ProdID 
    //CommandLineHandler.prod.ProdInstanceID 
    //CommandLineHandler.Alpha.AlhaValue() 
    //CommandLineHandler.Sleep.Miliseconds() 
    if (CommandLineHandler.Alpha.AlhaValue > 255) { 
        throw new Exception("Apha value out of bounds!"); 
    } 

} 
} 

public class MyCommandHandler 
{ 
private string[] values; 
public string SetInput { 
    set { values = Strings.Split(value, "-"); } 
} 

//Handle Prod command 
public struct prodstructure 
{ 
    public string ProdID; 
    public string ProdInstanceID; 
} 
public prodstructure prod { 
    get { 
        prodstructure ret = new prodstructure(); 
        ret.ProdID = GetArgsForCommand("prod", 0); 
        ret.ProdInstanceID = GetArgsForCommand("prod", 1); 
        return ret; 
    } 
} 

//Handle Apha command 
public struct Aphastructure 
{ 
    public int AlhaValue; 
} 
public Aphastructure Alpha { 
    get { 
        Aphastructure ret = new Aphastructure(); 
        ret.AlhaValue = Convert.ToInt32(GetArgsForCommand("alpha", 0)); 
        return ret; 
    } 
} 


//Handle Sleep command 
public struct SleepStructure 
{ 
    public int Miliseconds; 
} 
public SleepStructure Sleep { 
    get { 
        SleepStructure ret = new SleepStructure(); 
        ret.Miliseconds = Convert.ToInt32(GetArgsForCommand("sleep", 0)); 
        return ret; 
    } 
} 


private string GetArgsForCommand(string key, int item) 
{ 
    foreach (string c in values) { 
        foreach (string cc in Strings.Split(c.Trim, " ")) { 
            if (cc.ToLower == key.ToLower) { 
                try { 
                    return Strings.Split(c.Trim, " ")(item + 1); 
                } 
                catch (Exception ex) { 
                    return ""; 
                } 
            } 
        } 
    } 
    return ""; 
} 
} 
1 голос
/ 27 ноября 2008

Мне было бы немного неудобно использовать такую ​​командную строку. Первое, что я бы сказал, это «что означает первый« 1 »и почему он отличается от второго« 1 »?"

Каждый раз, когда я пишу утилиту командной строки, которая принимает аргумент, я думаю о том, как легко пользователю будет изучить все параметры. В этом случае это выглядит как сложная задача, ИМХО.

Возможно, хорошей идеей будет рефакторинг того, как пользователь передает аргументы. Существует причина, по которой большое количество программного обеспечения принимает параметры типа ключ / значение (например, myclient.exe -server = myServerName -config = debug). Это снимает большую нагрузку с пользователя, а также упрощает синтаксический анализ аргумента при попадании в ваш код.

0 голосов
/ 28 ноября 2008

Обычно, вы можете заменить большие конструкции if / else или switch / case на Словарь. Где ключ-критерий является ключом, а код для выполнения является значением.

Например, вы можете добавить Dictionary<string, ICommand> (или Dictionary<string, Type>), который вы заполняете перед анализом командной строки.

Когда вы перебираете переданные параметры командной строки, вы просто просматриваете их в словаре и «вызываете» для значения, которое является соответствующей командой (объектом) для выполнения (или, альтернативно, используете Activate.CreateInstance(/*dictionary-value*/), если вы сохранили тип вместо конкретного экземпляра объекта).

В C # 3.0 вы могли бы также что-то вроде Dictionary<string, System.Linq.Expressions.Expression<T>>, хотя это довольно близко приближает вас к фактическому выражению if - что вы можете захотеть иметь или нет. YMMV.

Некоторые библиотеки предоставляют вам простой анализ аргументов командной строки (как это обычно делал getopt () и др.) Или могут предоставить весь пакет, включая вызов действий при наличии определенных аргументов командной строки.

0 голосов
/ 27 ноября 2008

Я не думаю, что это слишком громко ..

private void Main() 
{ 
string c = "-t alpha 1 -prod 1 2 -sleep 200"; 

foreach (string incommand in Strings.Split(c, "-")) { 
    HandleCommand(Strings.Split(incommand.Trim, " ")); 
} 
} 


public void HandleCommand(string[] c) 
{ 
switch (c(0).ToLower) { 
    case "t": 
        Interaction.MsgBox("Command:" + c(0) + " params: " + c.Length - 1); 
        break; 
    case "prod": 
        Interaction.MsgBox("Command:" + c(0) + " params: " + c.Length - 1); 
        break; 
    case "sleep": 
        Interaction.MsgBox("Command:" + c(0) + " params: " + c.Length - 1); 
        break; 
} 
} 

Конечно, вместо того, чтобы делать то же самое в этих операторах switch, вызывайте соответствующие функции или код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...