使用. 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)使用了几个线程…但是如何解决呢?

使用. net 's Process类重定向标准输入/输出/错误流

问题可能是,因为您使用的是Readline,其中admin.exe应用程序输出的数据是顺序的,而不是在新行中。,尝试使用Read代替,并从中构建所需的字符串..

你也不必使用Environment.NewLine来写字符串后面跟着新行,使用WriteLine代替,所以:

process.StandardInput.WriteLine("uptime");