我正在尝试通过C#运行Plink 使用此代码
public void RunProcess(string FileName, string Arguments, bool EventWhenExit , bool IsWaitBeforeStart = true)
{
process = new Process();
process.OutputDataReceived += new DataReceivedEventHandler(OnDataReceivedEvent);
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.FileName = FileName; // Gets or sets the application or document to start.
process.StartInfo.Arguments = Arguments;//Gets or sets the set of command-line arguments to use when starting the application
if (IsWaitBeforeStart) Thread.Sleep(5000);
if (EventWhenExit)
{
process.EnableRaisingEvents = true;
process.Exited += new EventHandler(myprocess_Exited);
}
process.Start();
process.BeginOutputReadLine();
PID = process.Id;
ProcessInputStream = process.StandardInput;
}
当我运行Plink时(使用此arg:-telnet #IPAddr
)
我注意到最后一行只在我关闭进程时触发。
我的猜测是它保留了最后一行直到最后一行信号或类似的东西
如何使进程(不仅仅是Plink of course)在它的缓冲区中触发它所有的东西,而不是像特殊信号那样触发(如进程退出或新行)
答案 0 :(得分:1)
BeginOutputReadLine()
等待换行符或流的结尾。遗憾的是,没有BeginOutputRead()
方法可以提供您想要的行为。您确实可以访问process.StandardOutput
(StreamReader
),只要有数据可用就会返回Read()
个操作。
目前,控制台应用程序中的行一旦被换行符终止就会“完成”。因为对于这最后一行还没有输出换行符,你必须以某种方式确定它是否已经完成。请考虑以下示例:
Console.Write("This is the ");
Console.Write(" plink output ");
Console.Write(" that I'm trying to read");
LongRunningActivity();
Console.Write(".");
Console.WriteLine();
您可以单独接收这些数据段。线路什么时候完成?在LongRunningActivity()
之前?
因此,当尝试在换行符之前读取数据时,您必须考虑一些规则来确定消息是否已完成。
在单独的线程中执行此任务的示例:
...
process.Start();
Task.Factory.StartNew(new Action<object>(ReadFromStreamReader), process.StandardOutput);
void ReadFromStreamReader(object state)
{
StreamReader reader = state as StreamReader;
char[] buffer = new char[1024];
int chars;
while ((chars = reader.Read(buffer, 0, buffer.Length)) > 0)
{
string data = new string(buffer, 0, chars);
OnDataReceived(data);
}
// You arrive here when process is terminated.
}
void OnDataReceived(string data)
{
// Process the data here. It might contain only a chunk of a full line
// remember to use Invoke() if you want to update something in your form GUI
}