进程没有输出它的最后一行C#

时间:2014-10-13 06:33:58

标签: c# process plink

我正在尝试通过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)在它的缓冲区中触发它所有的东西,而不是像特殊信号那样触发(如进程退出或新行)

1 个答案:

答案 0 :(得分:1)

BeginOutputReadLine()等待换行符或流的结尾。遗憾的是,没有BeginOutputRead()方法可以提供您想要的行为。您确实可以访问process.StandardOutputStreamReader),只要有数据可用就会返回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
}