C#StandardOutput挂起,如何检测它等待输入?

时间:2015-04-23 16:13:47

标签: c# process cmd

我一直在使用C#处理进程(使用Process和ProcessStartInfo)。现在,只有一个问题真的困扰我,仍然无法找到解决问题的方法。

当应用程序“等待”时,StandardOutput将挂起。一些输入。 这意味着,如果您使用的是ReadToEnd,它将永远不会返回(因为实际的输入窗口是不可见的)。

现在,当我使用StandardInput提供输入时,这会产生问题。例如:

  1. 使用C#
  2. 启动流程
  3. 使用StandardInput输入命令。
  4. 开始阅读ouptut的流。
  5. 根据最后一个输出运行另一个。
  6. 现在这就是问题所在:我无法判断流程是在等待输入还是仍在生成输入,因为我的流程"得到"坚持从StandardOutput读取(它在同一个线程上完成)。

    我需要在命令运行后读取输出,运行一些算法,然后根据前面的命令输出运行另一个命令。

    是否有任何方法可以检测进程是否已完成加载命令并等待新输入?就像cmd一样?

2 个答案:

答案 0 :(得分:1)

试着跟随Peter回答,我还没有在StandardOutput结束时找到任何特殊的分隔符(我也检查了ErrorOutput)。

通过我的思考,为什么不用回声来模拟"分隔符?所以我提出了这个代码,它允许我运行一个特定的命令并立即在同一个线程上获得输出:

    /// <summary>
    /// A string used to write into the bash and allows us to detect when the bash finished to write it's output.
    /// </summary>
    const string delimiterString = "#WAITING";

    /// <summary>
    /// Runs the specified command and return it's output.
    /// </summary>
    /// <param name="command"></param>
    /// <returns></returns>
    public string RunCommand(string command)
    {
        sessionProcess.StandardInput.WriteLine(command);

        // Add a special string to be recognized when output is waiting
        sessionProcess.StandardInput.WriteLine("echo \"" + delimiterString + "\"");

        string output = "";
        int lastChr = 0;

        do
        {
            lastChr = sessionProcess.StandardOutput.Read();

            string outputChr = null;
            outputChr += sessionProcess.StandardOutput.CurrentEncoding.GetString(new byte[] { (byte)lastChr });
            output += outputChr;

            if (output.EndsWith(delimiterString))
            {
                // Remove delimeter
                output = output.Replace(Environment.NewLine + delimiterString, "");
                output = output.Replace(delimiterString + Environment.NewLine, "");

                // Console.Write(output);
                break;
            }

        } while (lastChr > 0);

        return output;
    }

答案 1 :(得分:0)

  

是否有任何方法可以检测进程是否已完成加载命令并等待新输入?就像cmd一样?

即使cmd.exe也不知道该进程是否已完成您的命令。 知道进程正在等待输入,但那是因为它负责提供从中获取输入的用户交互。即使在等待输入时,该过程也可以随时写出更多输出。

当重定向控制台进程的I / O时,您必须检测是否需要以与用户相同的方式提供输入:观察输出以获得提示。

鉴于您没有发布任何代码,不可能提供具体的建议,不要介意a good, minimal, complete code example可靠地重现问题。但一般来说,你应该能够循环,从输出中读取行,以及当你检测到提示时,然后执行一些代码来提供适当的响应。

例如:

string line;
while ((line = process.StandardOutput.ReadLine()) != null)
{
    Console.WriteLine(line);
    if (line.EndsWith("Enter next command: "))
    {
        process.StandardInput.WriteLine("next command");
    }
}