如何分析程序内的.exe参数?

时间:2008-11-27 14:13:40

标签: c# java .net python

我有一个可以有很多参数的程序(我们有超过+30个不同的选项)。

实施例: myProgram.exe -t alpha 1 -prod 1 2 -sleep 200

这是3个命令(最后来自命令模式对象),每个命令都包含一些参数。在代码中我们解析所有命令(以 - 开头)并获取参数的字符串列表(拆分所有空格)。所以实际上,我们有:string - >每个命令的String参数集合。

目前,我们使用字符串比较,我们可以完成所有工作(实例具体命令并返回ICommand接口)。问题是我们每次都需要做很多IF以获得良好的命令。

您是否有一些模式可用于从EXE中提取所有参数而不使用大量IF?

代码在C#中,但我认为逻辑也可以是任何其他语言......

9 个答案:

答案 0 :(得分:6)

(好吧,因为这是用Python标记的):

我们使用Python的optparse模块来实现此目的。它有比许多ifs更友好的API。

答案 1 :(得分:5)

创建一个哈希表,该表存储用于处理每个参数的函数指针(在C#中为委托),使用参数文本进行键控。然后,您只需在循环中浏览命令行,并根据哈希表查找的内容调用委托。

答案 2 :(得分:5)

C#的有用选项库:NDesk.Options

答案 3 :(得分:4)

getopt函数在C编程中非常常见。它可以为您解析参数。以下是C#的问题(和答案):GetOpt library for C#

特别是lappies实现看起来像是具有属性等的现代C#。

答案 4 :(得分:1)

使用这样的命令行我会有点不舒服。我要说的第一件事是“第一个'1'是什么意思,为什么它与第二个'1'不同?”

每当我编写一个接受参数的命令行实用程序时,我认为用户学习所有选项是多么容易。在这种情况下,它看起来像是一项艰巨的任务,恕我直言。

也许重构用户如何传递参数将是一个好主意。有很多软件采用键/值类型参数的原因(例如myclient.exe -server = myServerName -config = debug)它需要大量的用户负载,并且一旦它命中代码就简化了参数解析。

答案 5 :(得分:1)

只是为了好玩,您可以围绕整个事物创建一个包装器,并在代码中使用强名称。 更多的工作?是。但更有趣的是,一旦你向包装器添加了一个新命令,你就可以忘掉它了;)

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

答案 6 :(得分:1)

Java的答案,就像往常一样,是有人击败了你并发布了一个优秀的开源库来实现这一目标。看看Apache CLI

答案 7 :(得分:0)

我不认为这太过分了......

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语句中做同样的事情,而是调用适当的函数或代码。

答案 8 :(得分:0)

通常,您可以使用Dictionary替换大型if / else或switch / case结构。 if-criteria是密钥,执行代码是值。

例如,您可以在解析命令行之前填写Dictionary<string, ICommand>(或Dictionary<string, Type>)。

当您遍历传入的命令行选项时,只需在字典中查找它们并“调用”作为要执行的匹配命令(对象)的值(或者如果您使用Activate.CreateInstance(/*dictionary-value*/)存储类型而不是特定的对象实例。)

在C#3.0中,您还可以使用类似Dictionary<string, System.Linq.Expressions.Expression<T>>的内容,尽管这可以让您非常接近实际的if语句 - 这可能是您想拥有或不拥有的内容。 YMMV。

有些库只提供了对命令行参数的解析(就像传统的getopt()等),或者可以提供整个包,包括在存在特定命令行参数时调用操作。