我一直在使用C#处理进程(使用Process和ProcessStartInfo)。现在,只有一个问题真的困扰我,仍然无法找到解决问题的方法。
当应用程序“等待”时,StandardOutput将挂起。一些输入。 这意味着,如果您使用的是ReadToEnd,它将永远不会返回(因为实际的输入窗口是不可见的)。
现在,当我使用StandardInput提供输入时,这会产生问题。例如:
现在这就是问题所在:我无法判断流程是在等待输入还是仍在生成输入,因为我的流程"得到"坚持从StandardOutput读取(它在同一个线程上完成)。
我需要在命令运行后读取输出,运行一些算法,然后根据前面的命令输出运行另一个命令。
是否有任何方法可以检测进程是否已完成加载命令并等待新输入?就像cmd一样?
答案 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");
}
}