为什么不引发 OutputDataReceived 以进行提示,从而阻止发出 AutoResetEvent 信号?

Why is OutputDataReceived not being raised for prompt, preventing AutoResetEvent from being signaled?

我正在制作一个应用程序,它将产生一个具有命令行解释器的进程。我需要从另一台机器向此 CLI 提供命令。现在,我必须检测命令何时完成,所以我正在检查 CLI 的提示何时出现在我生成的进程的标准输出中。这是一段代码:

private string StartProcess(string input)
{
try
{
    StringBuilder output = new StringBuilder();
    StringBuilder error = new StringBuilder();

    AutoResetEvent commandFinished = new AutoResetEvent(false);

    ProcessStartInfo startInfo = new ProcessStartInfo()
    {
        FileName = "myprocess.exe",
        Arguments = "",
        UseShellExecute = false,
        CreateNoWindow = true,
        RedirectStandardOutput = true,
        RedirectStandardError = true,
        RedirectStandardInput = true,
        UserName = System.Environment.UserName
    };

    Process myProcess = new Process()
    {
        StartInfo = startInfo,
        EnableRaisingEvents = true
    };

    myProcess.OutputDataReceived += new DataReceivedEventHandler((sender, e) =>
    {
        if (e.Data != null)
        {
            string prompt = "user >";

            if (e.Data.Substring(e.Data.Length - prompt.Length).Equals(prompt))
            {
                Console.WriteLine("Received prompt! Sending CommandFinished signal!");
                commandFinished.Set();
                Console.WriteLine("CommandFinished signal set!");
            }
            else
            {
                output.AppendLine(e.Data);
            }
        }
        else
        {
            // Data finished
            Console.WriteLine("StdOut data finished! Sending CommandFinished signal!");
            commandFinished.Set();
            Console.WriteLine("CommandFinished signal set!");
        }
    });


    myProcess.ErrorDataReceived += new DataReceivedEventHandler((sender, e) =>
    {
        if (e.Data != null)
        {
            Console.WriteLine("Error Data received: " + e.Data.ToString());
            error.AppendLine(e.Data);
        }
    });

    myProcess.Start();
    myProcess.BeginOutputReadLine();
    myProcess.BeginErrorReadLine();

    Console.WriteLine("Executing input command: " + input);
    myProcess.StandardInput.WriteLine(input);

    Console.WriteLine("Waiting for input command to complete...");

    commandFinished.WaitOne();

    Console.WriteLine("Command complete!");

    return output.ToString();
}
catch (Exception ex)
{
    Console.WriteLine("EXCEPTION: " + ex.ToString());
    throw ex;
}
}

现在,代码挂在对 WaitOne() 的调用上。我很困惑为什么 - 我没有在输出中检测到 CLI 提示,而且我从来没有收到任何 WriteLines 告诉我在 OutputDataReceived 事件中收到了提示,或者收到的数据为空。 IE。当上一个命令完成并显示提示时,OutputDataReceived 事件没有被引发。

我提供的输入命令确实需要一段时间,但确实完成了。我在这里使用 AutoResetEvent 是不是错了?

如果没有 a good, minimal, complete code example,就不可能确定代码可能出了什么问题。但我可以看到一个明显的解释:

收到的每个 输出都会引发 OutputDataReceived 事件。即以换行符结尾的字符串。

没有关于您的外部流程的具体信息,我无法确定。但是大多数 CLI 类型的场景都涉及显示 没有 换行符的提示。 IE。提示被写入控制台,用户输入应该在提示后立即回显到控制台,而不是在下一行。

如果您的情况是这种情况,那么几乎可以肯定您没有检测到提示,因为不会单独针对提示引发事件。在上一个命令操作的最后一行输出之后,下一次将引发事件是 命令已通过标准输入发送到进程之后。这显然为时已晚,无法知道何时发送该命令。 :)

要使其正常工作,您将必须通过不是基于行的其他可用机制之一从流程中读取输入。