问题描述
我一直在使用C#进程(使用Process和ProcessStartInfo)相当一段时间。现在,只有一个问题,真的困扰我,仍然没有找到一种方法来解决它。
I have been working with processes (using the Process and ProcessStartInfo) with C# quite some time. Now, there is only one question that really bothered me and still haven't managed to find a way to work it out.
当应用程序是等待一些输入。
这意味着,如果你使用ReadToEnd它将永远不会返回(因为实际的输入窗口是不可见的)。
The StandardOutput will hang when the application is "waiting" for some input.Which means, if you are using ReadToEnd it will never return (as the actual input window is invisible).
现在, m使用StandardInput提供输入。例如:
Now, this creates a problem when I'm using the StandardInput to provide the input. For example:
- 使用C#启动过程
- 使用StandardInput输入命令。
- 开始阅读ouptut的信息流。
- 根据最后一个输出执行另一个。
- Starting the process with C#
- Entering a command using StandardInput.
- Start reading the stream for the ouptut.
- Running another one based on the last output.
现在这是问题:我不能告诉进程是等待输入还是仍然生成一个,因为我的进程被卡住从StandardOutput读取(它是在
Now this is the problem: I can't tell whether the process is waiting for input or it's still generating one, as my process "gets" stuck to read from the StandardOutput (it's done on the same thread).
我需要在命令运行后读取输出,运行一些算法,然后根据上一个命令输出运行另一个命令。
I need to read the output after my command ran, run some algorithms and then run another command based on the previous command output.
有没有什么方法来检测进程是否运行完成加载我的命令和等待新的输入?就像cmd一样?
Is there is any way of detecting if the process running finished loading my command and waiting for new input? Just like the cmd does?
推荐答案
尝试按照Peter的回答,我没有找到任何特殊的分隔符StandardOutput(我也检查ErrorOutput)。
Trying to follow Peter answer, I haven't found any special delimiter at the end of the StandardOutput (I checked the ErrorOutput as well).
通过我想,为什么不使用echo来模拟分隔符?所以我把这个代码,让我运行一个特定的命令,并立即获得输出在同一个线程:
Thinking of this through I thought, why not used echo to "simulate" a delimiter? So I put up this code which allows me to run a specific command and obtain the output immediately on the same thread:
/// <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;
}
这篇关于C#StandardOutput挂起,我如何检测它在等待输入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!