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,最后才启动进程——这顺序完全颠倒了。正确的流程应该是:
- 配置
ProcessStartInfo - 初始化
Process并绑定事件 - 启动进程
- 获取
StandardInput - 开始异步读取输出
修改后的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
相关产品推荐
相关产品推荐

