一旦你的脚本开始变得更加高级,你就会想利用这个参数来让你的脚本执行多种操作。例如,如果你在写一个气闸脚本,你会想告诉脚本让一个气闸循环进出,甚至让哪个气闸循环。我不会告诉你如何写一个气闸脚本,但我将以此为例,向你展示如何检测和处理与这种脚本有关的参数。可编程块API有一个内置的命令行解析器,这是由你提供的,它被设计成快速和分配友好,以及易于使用。
对于那些只想继续使用它的人,这里是本教程中使用的简单演示脚本的链接。气闸门
这段代码初始化了命令行解析器,并试图解析传入的参数。如果它找到了参数,TryParse方法将返回true
MyCommandLine _commandLine = new MyCommandLine();
public void Main(string argument)
{
if (_commandLine.TryParse(argument)) {
// The command line parser found arguments in the string.
}
}
传统的命令行中包含了argument
和switch
cycle "Airlock 1" in -emergency
argument: 是以空格为间隔的字符串(cycle)或("Airlock 1")字符串。当argument串有空格分开的过个单词组成,需要用引号概括。
argument的访问和数组一样,通过位置访问元素。第一个元素下标是0,依此类推。
格式: -emergency
访问:switches放置在任何地方都行,不通过位置访问。
eg1和eg2显示,放置 -emergency 开关的位置无关紧要,它不会影响参数的索引。
cycle "Airlock 1" in -emergency #eg1
-emergency cycle "Airlock 1" in # eg2
0: cycle
1: "Airclock 1"
2: in
switch:
-emergency
0: cycle
1: "Airclock 1"
2: in
switch:
-emergency
MyCommandLine类提供方法:Switch(name),获取名字为name的switch的参数。
// check if the -myflag switch is set
bool switchIsSet = _commandLine.Switch("myflag");
// retrieve the first argument of the string (either a word or a "quoted string"). The quotes are removed for you.
string arg = _commandLine.Argument(0);
首先,我们将需要一种方法来区分命令。第一个参数,当然,将是命令指示器。我们将创建一个字典来保存这些命令。
Dictionary _commands = new Dictionary(StringComparer.OrdinalIgnoreCase);
注意,我们传入了一个不区分大小写的字符串比较器,所以我们可以接受CYCLE以及cycle。接下来我们需要初始化这些命令。这一点我们在脚本构造函数中完成。
//_commands字典,绑定arguments和action
public Program()
{
// Associate the Cycle method with the cycle command
_commands["cycle"] = Cycle;
}
public void Cycle()
{
// This method will hold the code to perform the desired action
}
public void Main(string argument)
{
// 解析命令行参数
if (_commandLine.TryParse(argument))
{
Action commandAction;
// Retrieve the first argument. Switches are ignored.
string command = _commandLine.Argument(0);
// Now we must validate that the first argument is actually specified,
// then attempt to find the matching command delegate.
if (command == null)
{
Echo("No command specified");
}
else if (_commands.TryGetValue(command, out commandAction))
{
///< 在Programs()中绑定了"cycle"字符串和函数Cycle()
///< 从字典_commands中取出"cycle"对应的Action执行
commandAction();
}
else
{
Echo($"Unknown command {command}");
}
}
}
public void Cycle()
{
//解析switch参数emergency
bool emergencyCycle = _commandLine.Switch("emergency");
//命令行中解析气闸门的名字,用于cycle。这里index=1。没有气闸门就退出
string airlockName = _commandLine.Argument(1);
if (airlockName == null)
{
Echo("Cannot cycle, no airlock specified");
return;
}
// Argument no. 2 should be either "in" or "out", indicating
// which direction to cycle
///< 命令行中读取index=2的参数,确定进出方向in/out
string direction = _commandLine.Argument(2);
if (direction == null)
{
Echo($"Cannot cycle {airlockName}, no direction specified");
return;
}
if (string.Equals(direction, "in", StringComparison.OrdinalIgnoreCase))
{
Echo($"Cycling airlock {airlockName} in...");
// TODO: Begin the cycling of the airlock
}
else if (string.Equals(direction, "out", StringComparison.OrdinalIgnoreCase))
{
Echo($"Cycling airlock {airlockName} out...");
// TODO: Begin the cycling of the airlock
}
else
{
// The argument was none of the expected values
Echo($"Cannot cycle {airlockName}, cannot understand direction {direction}");
}
}
MyCommandLine _commandLine = new MyCommandLine();
Dictionary _commands = new Dictionary(StringComparer.OrdinalIgnoreCase);
public Program()
{
_commands["cycle"] = Cycle;
}
public void Cycle()
{
// Check if the "emergency" switch is set.
bool emergencyCycle = _commandLine.Switch("emergency");
// Argument no. 1 is the name of the airlock to cycle
string airlockName = _commandLine.Argument(1);
if (airlockName == null)
{
Echo("Cannot cycle, no airlock specified");
return;
}
// Argument no. 2 should be either "in" or "out", indicating
// which direction to cycle
string direction = _commandLine.Argument(2);
if (direction == null)
{
Echo($"Cannot cycle {airlockName}, no direction specified");
return;
}
if (string.Equals(direction, "in", StringComparison.OrdinalIgnoreCase))
{
Echo($"Cycling airlock {airlockName} in...");
// TODO: Begin the cycling of the airlock
}
else if (string.Equals(direction, "out", StringComparison.OrdinalIgnoreCase))
{
Echo($"Cycling airlock {airlockName} out...");
// TODO: Begin the cycling of the airlock
}
else
{
// The argument was none of the expected values
Echo($"Cannot cycle {airlockName}, cannot understand direction {direction}");
}
}
public void Main(string argument)
{
if (_commandLine.TryParse(argument))
{
Action commandAction;
// Retrieve the first argument. Switches are ignored.
string command = _commandLine.Argument(0);
// Now we must validate that the first argument is actually specified,
// then attempt to find the matching command delegate.
if (command == null)
{
Echo("No command specified");
}
else if (_commands.TryGetValue(_commandLine.Argument(0), out commandAction))
{
// We have found a command. Invoke it.
commandAction();
}
else
{
Echo($"Unknown command {command}");
}
}
}