【问题标题】:Why can't I get the output of a C++ program using Process in C#?为什么我不能在 C# 中使用 Process 获得 C++ 程序的输出?
【发布时间】:2015-03-12 01:56:37
【问题描述】:

我有一个 C++ 程序,它使用wprintf_s 函数将结果打印到命令行。但是当我在 C# 中使用Process 来读取程序的输出时,我无法得到它的任何字眼。然而,当我在wprintf_s 语句之后添加fflush(stdout) 时,我终于可以在我的C# 程序中读取标准输出了。

我用来启动进度的代码是:

var proc = new Process {
    StartInfo = new ProcessStartInfo {
        FileName = "FILENAME",
        UseShellExecute = false,
        RedirectStandardOutput = true,
        CreateNoWindow = true
    }
};
proc.Start();
StringCollection values = new StringCollection();

proc.OutputDataReceived += (s, args) => {
    lock (values) {
        values.Add(args.Data);
    }
};
proc.BeginOutputReadLine();
proc.WaitForExit();

谁能告诉我为什么fflush(stdout) 会起作用?

【问题讨论】:

  • 因为它正在被缓冲。
  • @OldProgrammer 如果没有fflush,输出将始终在缓冲区中?
  • 我在运行 Perl 脚本时遇到了类似的问题,它缓冲了标准输出,然后在脚本完成后立即全部刷新到我的 C# 应用程序中。

标签: c# c++ process redirectstandardoutput


【解决方案1】:

输出在 C++ 进程中被缓冲,并将一直保持到缓冲区满或被刷新,例如通过调用fflush()、关闭流或其他依赖于操作系统的原因。

fflush() 只会将输出缓冲区中的任何数据写入流。

如果您不想显式调用fflush(),可以考虑通过调用setbuf() 并为第二个参数设置一个NULL 指针来设置输出流的无缓冲模式:

#include <stdio.h>
#include <unistd.h>

int main()
{
    setbuf(stdout, (char *)NULL);

    while (1)
    {
        fputs("hi there\n", stdout);
        sleep(1);
    }
}

现在输出将立即出现。

请注意,如果stdout 是终端,则setbuf(f, NULL) 是不必要的,因为这是终端设备的默认行为。如果stdout 是一个管道,那么setbuf(f, NULL) 将使其无缓冲。

【讨论】:

  • 感谢您的解释。我想知道每当我使用Process 启动命令行程序并重定向输出流时,程序的stdout 是否会成为管道?
  • 通过“管道”我指的是一个进程的输出连接到另一个进程的输入的概念。无论如何,缓冲发生在子进程中,因此禁用子进程中的缓冲可以解决问题。可能重定向是通过管道实现的,但我对 .NET 的熟练程度不足以肯定地说。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-25
  • 2019-03-24
  • 2022-01-15
  • 2022-10-05
  • 2011-07-10
  • 2023-04-01
相关资源
最近更新 更多