【问题标题】:Running Series of commands with C# in cmd在 cmd 中使用 C# 运行一系列命令
【发布时间】:2016-12-14 14:55:59
【问题描述】:

最近,我们一直在研究 Berkley Pacman AI 课程。我们必须分析 alpha、epsilon 和 gamma 的变化值对我们的 AI 有何影响。

要将命令直接插入 CMD,我们告诉 CMD:

pacman.py -q -p PacmanQAgent -x 2000 -n 2010 -l smallGrid -a epsilon=0.08,alpha=0.3,gamma=0.7

现在,我想运行一系列测试,更改这些给定变量的值。所以我想打开 CMD,运行很多命令(本质上是相同的)并将输出保存在一个文本文件中。我在 StackExchange 上找到了一些信息,它给了我以下代码:

string command = "pacman.py -q -p PacmanQAgent -x 2000 -n 2010 -l smallGrid -a epsilon=0.08,alpha=0.3,gamma=0.7";
Process.Start("CMD.exe", command);

虽然它打开了 CMD,但它似乎什么也没做。 CMD 的目录也是我的解决方案的目录。 这应该很容易(尽管 Windows API 可能很难使用)

谁能帮忙,或者给我一个通用的解决方案?

【问题讨论】:

标签: c# windows cmd filepath


【解决方案1】:

试试 ProcessStartInfo 类。 MSDN ProcessStartInfo

因为这是针对 AI 课程的。我可能会做一个PacmanArgument 类。 PacmanArgument 将具有每个可能的命令行参数的属性和要调用的自定义 ToString 方法。假设输出可以被读取为适应度,以编程方式为诸如遗传算法之类的东西生成参数会更容易。

主要功能:

double MAX_EPSILON = 1; //I assume there are constraints
//create packman agent with initial values
PacmanAgent agent = new PackmanAgent(0,0,0) //epsilon,alpha,gamma
//create Process info 
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "pacman.py"
psi.WorkingDirectory = @"C:/FilePathToPacman"
psi.RedirectStandardOutput = true;
psi.UseShellExecute = false;

string output;
Console.WriteLine("***** Increasing Eplison Test *****");
while( agent.Epsilon =< MAX_EPSILON )
{
    psi.Arguments = agent.GetArgument();
    // Start the process with the info we specified.
    // Call WaitForExit and then the using-statement will close.
    using (Process process =  Process.Start(psi))
    {
        output = process.StandardOutput.ReadToEnd(); //pipe output to c# variable
        process.WaitForExit(); //wait for pacman to end
    }

    //Do something with test output
    Console.WriteLine("Epsilon: {0}, Alpha: {1}, Gamma: {2}",agent.Epsilon,agent.Alpha,agent.Gamma );
    Console.WriteLine("\t" + output);

    agent.IncrementEpsilon(0.05); //increment by desired value or default(set in IncrementEpsilon function)
}

吃豆人代理类:

public class PacmanAgent
{
    private string ArgumentBase = "-q -p PacmanQAgent -x 2000 -n 2010 -l smallGrid -a ";
    [Range(0, 1, ErrorMessage = "Value for {0} must be between {1} and {2}.")]
    public double Epsilon { get; set; }
    [Range(0, 1, ErrorMessage = "Value for {0} must be between {1} and {2}.")]
    public double Alpha { get; set; }
    [Range(0, 1, ErrorMessage = "Value for {0} must be between {1} and {2}.")]
    public double Gamma { get; set; }

    public PacmanAgent(int epsilon, int alpha , int gamma )   
    {
         Epsilon = epsilon;
         Alpha = alpha; 
         Gamma = gamma; 
    }   

    public string GetArgument()
    {
        string argument = string.Format("{0} epsilon={1}, alpha={2}, gamma={3}", ArgumentBase, Epsilon, Alpha, Gamma)
        return argument
    }

    public void IncrementEpsilon(double i = 0.01)
    {
        Epsilon += i;
    }
    public void IncrementAlpha(double i = 0.01)
    {
        Alpha += i;
    }
    public void IncrementGamma(double i = 0.01)
    {
        Gamma += i;
    }
}

*我是在 IDE 外面写的,所以请原谅任何语法错误

【讨论】:

  • 这非常了不起!我今天没有时间研究它,但我所看到的很有意义。我自己无法做到这一点,因为我从未使用 C# 管理其他进程
  • 现在文件路径有问题。试图弄清楚。您还忘记添加psi.UseShellExecute = false;,但现在已修复。
  • @RichardDirven 这对你有用吗?我最近只使用过少量进程,并且没有任何设置来测试此代码,所以我很好奇。
  • 代码已编译,但除了启动 CMD 之外似乎没有做任何事情。最后我写了两个程序,一个用于创建一个巨大的批处理文件,其中包含所有不同的 epsilon、alpha 和 gamma 值。然后我运行批处理,然后我编写了一个程序来解释它给我的输出。
  • @RichardDirven 看起来如果我们合并Run Python Script From C# 将文件名设置为 c:\python26\python.exe (或适当的位置)并将整个命令的参数设置为pacman.py -q -p PacmanQAgent -x 2000 -n 2010 -l smallGrid -a epsilon=0.08,alpha=0.3,gamma=0.7 它可能会工作
【解决方案2】:

您可以首先构建一个包含所有 pacman.py 命令的临时批处理文件。使用标准方法在 C# 中创建文件。使用标准 CMD.EXE 管道功能附加到文件(下面的 myfile.txt)。

您的临时 .BAT 文件如下:

cd \mydirectory
pacman.py -q -p PacmanQAgent -x 2000 -n 2010 -l smallGrid -a epsilon=0.08,alpha=0.3,gamma=0.7 >> myfile.txt
pacman.py -q -p PacmanQAgent -x 2000 -n 2010 -l smallGrid -a epsilon=0.08,alpha=0.3,gamma=0.7 >> myfile.txt
pacman.py -q -p PacmanQAgent -x 2000 -n 2010 -l smallGrid -a epsilon=0.08,alpha=0.3,gamma=0.7 >> myfile.txt

然后以与您已经使用的方法类似的方式运行它:

var command = "mytemp.bat"
processInfo = new ProcessStartInfo("cmd.exe", "/c " + command);
processInfo.CreateNoWindow = true;
processInfo.UseShellExecute = false;
process = Process.Start(processInfo);
process.WaitForExit();

如果您不想在批处理文件中通过管道传输,也可以将 Process 重定向为标准输出并将其读入 C# 中的字符串变量。

【讨论】:

  • 那么我的程序也必须多次更改临时 bat 文件?
  • 我会设想在您需要时即时构建它,执行它,然后删除它。因此,您正在打开一个名为“myfile.bat”的文本文件的流,输入上面的 CMD.EXE 命令,关闭它,然后使用 Process.Start() 运行它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-04
  • 1970-01-01
  • 1970-01-01
  • 2016-06-19
相关资源
最近更新 更多