【问题标题】:command line input and UseShellExecute == true命令行输入和 UseShellExecute == true
【发布时间】:2012-11-30 13:40:41
【问题描述】:

我有一个程序,基本上剩下的就是通过 CMD.exe 调用命令。

我需要在当前工作目录中打开 CMD.exe(我知道我可以只执行 Porcess.Start(CMD.exe))

然后我需要让程序在 cmd.exe 中键入一个特定的字符串。同时留在我当前的工作目录中。我不能使用“UseShellExecute == false”,因为它会杀死 shell,我需要 shell 才能工作。

显然我需要更具体。所以,我试图写入 cmd.exe 的文本是"clingo.exe \"Constants.txt\" \"Solver.txt\" \"Nodes.txt\" > \"Solved.txt\""。 clingo.exe 是一个答案集编译器,我在常量、求解器和节点文件上使用它来获得通过管道传输到 Solved 的解决方案。所有这些文件都在一个目录中。

【问题讨论】:

  • 你试过Process p = new Process(); p.StartInfo = new ProcessStartInfo("cmd"); p.StartInfo.Arguments = "everything else here";
  • 欢迎您!看起来您在有效使用 Process 类时遇到了问题。如果您提供迄今为止尝试过的内容,您将获得更好的答案,并更好地理解问题。

标签: c# command-line cmd


【解决方案1】:

首先,我对您认为UseShellExecute=false 不适合您的原因感兴趣。是不是你没有正确使用它?

这是您的最佳选择。这适用于 99% 的应用:

ProcessStartInfo psi = new ProcessStartInfo
{
    FileName = "clingo.exe",
    Arguments = "\"Constants.txt\" \"Solver.txt\" \"Nodes.txt\"",
    RedirectStandardOutput = true,
    UseShellExecute = false
};

using(Process p = Process.Start(psi))
using(Stream s = File.Create("Solved.txt"))
{
    p.StandardOutput.CopyTo(s);
    p.WaitForExit();
}

这是一个罕见的应用程序的选项,它不喜欢以标准方式传递的 args,但适用于 cmd.exe:

ProcessStartInfo psi = new ProcessStartInfo
{
    FileName = "cmd.exe",
    RedirectStandardInput = true,
    UseShellExecute = false // note this applies to cmd.exe specifically,
                            // NOT the processes that you start from cmd.exe
};

using(Process p = Process.Start(psi))
{
    p.StandardInput.WriteLine("clingo \"Constants.txt\" \"Solver.txt\" \"Nodes.txt\" > \"Solved.txt\"");
    p.StandardInput.WriteLine("exit");
    p.WaitForExit();
}

您可能还需要重定向 StandardOutput 和 StandardError 才能使这个正常工作——我忘了​​!

【讨论】:

  • 我同意我做错了什么..你之前的工作很好..我认为问题是我认为它会像我手动打开 cmd.exe 并键入一样运行它是手动的,当我手动输入时..我没有意识到我需要毕业并对其进行操作。它现在可以 100% 使用您之前的功能
  • 很高兴听到这个消息! Process.Start 有点低级—— cmd.exe 在幕后调用了类似的东西,但也在这里发挥了自己的魔力。 >Solved.txt 位不是启动过程的一部分,而是特定于 cmd.exe 的语法,用于将 > 左侧命令的标准输出重定向到右侧的文件。使用Process.Start时,需要自己做。
  • 是的,这完全有道理,我只是 100% 不熟悉来自这个场所的系统调用(由于课程,在 UNIX 机器上进行了更多练习。在此之前从来不需要这个实用程序。它似乎完美地工作这让我感到非常高兴和如释重负。我可能终于在凌晨 3 点之前上床睡觉了=)
【解决方案2】:

您可以尝试传递参数,但请确保您的 exe 参数正确

ProcessStartInfo proc = new ProcessStartInfo();
proc.FileName = @"C:\clingo.exe \Constants.txt\ \Solver.txt\ \Nodes.txt\ > \Solved.txt\";
proc.Arguments = @"10.2.2.125";
Process.Start(proc);

【讨论】:

  • \clingo.exe \Constants.txt\ \Solver.txt\ \Nodes.txt\ > \Solved.txt\实际上是在cmd中输入时执行
【解决方案3】:

为什么需要从命令行启动进程?这个呢?

var process = new Process { StartInfo = new ProcessStartInfo("cmd", "/c clingo.exe Constants.txt Solver.txt Nodes.txt") };
process.Start();
process.StartInfo.RedirectStandardOutput = true;
process.WaitForExit();
//do something with process.StandardOutput, this has the results

这里需要注意的一些技巧。首先,使用 cmd 的 /c 参数,它会使提示立即退出。其次,根据您的上下文,您可能需要设置process.StartInfo.CreateNoWindow = true。最后,请注意,如果输出超出缓冲区,重定向标准输出可能会导致应用程序挂起。如果您希望它不仅仅是一点点数据,您将需要特别努力地读出它。

【讨论】:

  • > Solved.txt 位是用于将 cligo 的标准输出重定向到 Solved.txt 的 cmd 脚本,因此这不起作用(但可以轻松修复)。
  • 此外,一些罕见的应用程序(想到 ImageMagick)由于某种原因无法使用此功能。对于这些,您实际上确实需要使用 cmd.exe、重定向标准输入并编写命令来启动应用程序。
  • 据我所知,我必须从 cmd.exe 运行 cligo.exe 才能正常工作。但我会尝试你的答案。
  • 哎呀,感谢@CoryNelson,解决了这个问题。另外,改为使用 cmd.exe
  • 我相信 cligo.exe 是这些应用程序之一。问题是当我关闭外壳时,它似乎实际上并没有接受任何输入。
猜你喜欢
  • 2011-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-21
  • 2012-07-04
  • 1970-01-01
  • 1970-01-01
  • 2014-04-20
相关资源
最近更新 更多