C#实时捕获进程的标准输出/错误输出

3

我正在开发一个C#应用程序,需要运行外部控制台进程(例如Python脚本)并实时接收脚本的输出数据。Python脚本类似于以下内容:

import time
while 1:
    print("Hi Foo!")
    time.sleep(.3)

以下C#代码可以实时将Python脚本输出打印在C#控制台上:
static void Main(string[] args)
{
    using (Process process = new Process())
    {
        process.StartInfo.FileName = "python.exe";
        process.StartInfo.Arguments = "test.py";
        process.StartInfo.UseShellExecute = false;
        process.Start();
        process.WaitForExit();
    }
}

然而,当我尝试手动捕获输出数据并将它们写入控制台时,我失败了。根据其他文章的建议,推荐的解决方案是这样的,但它不起作用:

static void Main(string[] args)
{
    using (Process process = new Process())
    {
        process.StartInfo.FileName = "python.exe";
        process.StartInfo.Arguments = "test.py";
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.RedirectStandardOutput = true;
        process.EnableRaisingEvents = true;
        process.OutputDataReceived += (s, e) => Console.WriteLine(e.Data);
        process.Start();
        process.BeginOutputReadLine();
        process.WaitForExit();
    }
}

process.StandardOutput.ReadToEnd() 是以阻塞模式工作的,它等待进程退出并一次性返回全部输出。实时输出捕获的问题是什么?我该如何解决它?


首先,您需要确保 Python 脚本端没有发生缓冲(https://stackoverflow.com/a/31174617),然后您可以使用类似于此的内容(https://stackoverflow.com/a/33859530)来读取不完整的行(对我来说,看起来像是您的脚本没有发出换行符)从标准输出。 - user4003407
可能是禁用输出缓冲的重复问题。 - Kirk Larkin
1个回答

4
        using (var process = new Process())
        {
            process.StartInfo.FileName = @"python.exe";
            process.StartInfo.Arguments = "-u test.py";
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.UseShellExecute = false;
            process.Start();

            while (!process.StandardOutput.EndOfStream)
            {
                string line = process.StandardOutput.ReadLine();
                Console.WriteLine(line);
                // do something with line
            }
            process.WaitForExit();
            Console.Read();
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接