You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#进程输出重定向失效问题:向外部进程发送输入并捕获输出失败

问题排查与解决方案

咱们先揪出最致命的问题——你的StartProcessWithOutputRedirection方法里,process.Start()被注释掉了!进程都没启动,当然不会有任何输出事件触发,这是核心原因。

不过就算启动了进程,还有两个坑需要填上:

1. C程序的输出缓冲导致数据无法即时传递

当C程序的标准输出被重定向到管道(也就是你这里的C#进程)时,stdio库会默认使用全缓冲模式,而非终端环境下的行缓冲。这意味着printf的内容会被攒在缓冲区里,不会立刻发送给C#进程,自然触发不了OutputDataReceived事件。

解决办法

在C程序的printf之后手动刷新缓冲区:

#include <stdio.h>
#include <stdbool.h>
int main(){
    while(true){
        char buff[1000];
        // 注意:去掉多余的s,%[^\n]已经是完整的格式说明符
        scanf(" %[^\n]", buff);
        printf("\nechoed : %s\n",buff);
        // 强制刷新输出缓冲区,确保数据即时传递
        fflush(stdout);
    }
}

或者你也可以在程序开头直接设置stdout为无缓冲模式:

#include <stdio.h>
#include <stdbool.h>
int main(){
    // 设置标准输出为无缓冲
    setvbuf(stdout, NULL, _IONBF, 0);
    while(true){
        char buff[1000];
        scanf(" %[^\n]", buff);
        printf("\nechoed : %s\n",buff);
    }
}

2. C#进程启动和事件注册的顺序错误

你的C#代码里,先获取了StandardInput,再调用BeginOutputReadLine,最后才启动进程——这顺序完全颠倒了。正确的流程应该是:

  1. 配置ProcessStartInfo
  2. 初始化Process并绑定事件
  3. 启动进程
  4. 获取StandardInput
  5. 开始异步读取输出

修改后的C#方法代码

static void StartProcessWithOutputRedirection()
{
    ProcessStartInfo startInfo = new ProcessStartInfo();
    startInfo.CreateNoWindow = false;
    startInfo.UseShellExecute = false;
    startInfo.FileName = filePath;
    startInfo.WindowStyle = ProcessWindowStyle.Hidden;

    // 标准输入输出重定向
    startInfo.RedirectStandardOutput = true;
    startInfo.RedirectStandardError = true;
    startInfo.RedirectStandardInput = true;

    try
    {
        Process process = new Process();
        process.StartInfo = startInfo;
        process.OutputDataReceived += MyProcOutputHandler;
        process.ErrorDataReceived += MyProcOutputHandler;

        // 先启动进程!这是核心步骤
        process.Start();
        // 启动后再获取输入流
        processStreamWriter = process.StandardInput;
        // 开始异步读取输出
        process.BeginOutputReadLine();
        process.BeginErrorReadLine();
        // WaitForExit会阻塞当前线程,不过你是在单独线程里调用,没问题
        process.WaitForExit();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

额外注意点

  • 你的C程序里scanf(" %[^\n]s", buff);的s是多余的,%[^\n]已经是一个完整的格式说明符,用来读取直到换行符的所有字符,加上s会导致匹配失败,输入处理异常,一定要去掉。
  • 确保my_program.exe的路径是正确的,建议使用绝对路径避免找不到文件的问题。

按照上面的修改,你的程序应该就能正常触发输出事件,实现输入输出的交互了。

内容的提问来源于stack exchange,提问作者Akagi Akira

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 13:14:06