使用. net 's Process类重定向标准输入/输出/错误流
本文关键字:标准输入 重定向 输出 错误 Process net 使用 | 更新日期: 2023-09-27 18:05:34
我正在尝试为基于控制台的交互式应用程序编写包装器。为此,我使用c#和Process
类。我试图重定向stdin
/out
/err
,但它不工作。
示例代码:
ProcessStartInfo startInfo = new ProcessStartInfo("admin.exe");
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardInput = true;
startInfo.UseShellExecute = false;
Process process = Process.Start(startInfo);
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.OutputDataReceived += (s, e) => Console.WriteLine(e.Data);
process.ErrorDataReceived += (s, e) => Console.WriteLine(e.Data);
while (true)
{
process.StandardInput.Write("uptime" + Environment.NewLine);
process.StandardInput.Flush();
Thread.Sleep(1000);
}
Console.ReadKey();
什么也不会发生。但是,如果我启动admin.exe
并写入uptime
,则输出输出。
互联网上的所有解决方案都使用ReadToEnd
,但我不能使用这个,因为我有一个动态通信,我必须读取stdout
/err
并写入stdin
。
有人知道吗?
更新我在链接的线程上玩了张贴的zip。然后我尝试创建一个小的"概念验证"代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Threading;
namespace ConsoleApplication3
{
class Program
{
private static void Read(StreamReader reader)
{
new Thread(() =>
{
while (true)
{
int current;
while ((current = reader.Read()) >= 0)
Console.Write((char)current);
}
}).Start();
}
static void Main(string[] args)
{
ProcessStartInfo startInfo = new ProcessStartInfo(@"cmd.exe");
startInfo.CreateNoWindow = true;
startInfo.ErrorDialog = false;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
Read(process.StandardOutput);
Read(process.StandardError);
while (true)
process.StandardInput.WriteLine(Console.ReadLine());
}
}
}
它工作完美:-)
但与admin.exe
它不工作?admin.exe
不使用任何复杂的输入法,也不需要输入密码。
我知道admin.exe
是用c写的,在linux上用mingw编译的。所以我创建了一个小的虚拟工具:
#include <stdio.h>
int main() {
int readed;
while ((readed = fgetc(stdin)) >= 0)
fputc((char)readed, stdout);
}
这个工具只回显输入的文本/行。我用i586-mingw32msvc-gcc
编译并复制到我的windows机器上。在那里,我使用这篇文章顶部的程序与dummy.exe
进行通信。这行不通。没有显示回声。但是为什么呢?
我也用微软c++编译器编译了伪代码,效果相同。
更新2
(顺便说一句:感谢Tim Post)
我一直在努力。我尝试创建一个c- tool,它和我的c#工具一样。我使用_popen
,但效果是,输出在过程结束时显示。嗯,不太好。
我找到了这个windows的替代命令shell:
https://stackoverflow.com/questions/440269/whats-a-good-alternative-windows-console http://sourceforge.net/projects/console/它似乎有效。它实时获取标准输出/错误,可以重定向标准输出和admin.exe
工作。而且它是开源的。也许我会在c++代码中找到解决方案。
我不太会c++,所以很难,但我会试一试。也许我必须用C/c++写一个"清晰的"重定向包装器,然后在c#中使用它。
如果有人有想法,请说出来,因为其他方式可能很难(对我来说^^):-)
谢谢。
问好3
更新嗯,我认为这是因为子进程(admin.exe
)使用了几个线程…但是如何解决呢?
问题可能是,因为您使用的是Readline
,其中admin.exe
应用程序输出的数据是顺序的,而不是在新行中。,尝试使用Read
代替,并从中构建所需的字符串..
你也不必使用Environment.NewLine
来写字符串后面跟着新行,使用WriteLine
代替,所以:
process.StandardInput.WriteLine("uptime");