我正在制作一个应用程序,它将产生一个具有命令行解释器的进程。我需要从另一台机器向这个CLI提供命令。现在,我必须检测命令何时完成,因此我正在检查CLI提示何时出现在我产生的进程的标准输出中。这里有一段代码:为什么OutputDataReceived不会为提示而引发,从而阻止AutoResetEvent发出信号?
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
事件中收到提示,或收到的数据为空。即当前一个命令完成并且显示提示时,OutputDataReceived
事件不会引发。
我提供的输入命令确实需要一段时间,但确实完成了。我在这里使用AutoResetEvent错误吗?
您是否确认通风管理器正在被调用?如果我不得不猜测,我敢打赌问题是输出数据末尾还有其他内容,比如空格,或者提示符被分割为多个DataReceived事件(可能是“用户”和一个对于“>”)。 –
您还需要处理'e.Data.Length - prompt.Length'小于0 –
@DarkFalcon,我实际上捕获输出,如果我没有得到提示,所以我应该看到提示(或部分如果是这样的话,我只能看到输出的前几行,然后挂起。 – Tino