Umleiten von standard-Eingabe/Ausgabe/error streams mit .NET Process-Klasse

Ich versuche zu schreiben ein wrapper für eine interaktive Konsole-basierte Anwendung. Für diese verwende ich C# und das Process Klasse. Ich versuche umleiten stdin/out/err, aber es funktioniert nicht.

Beispiel-code:

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();

Nichts passiert. Aber wenn ich die starte admin.exe und schreiben uptime, wird die Ausgabe gedruckt.

Alle Lösungen im internet verwenden ReadToEnd, aber ich kann dies nicht verwenden, weil ich eine dynamische Kommunikation, auf dem ich Lesen stdout/err und schreiben stdin.

Hat jemand eine Idee?

Update

Spielte ich mit dem geposteten zip auf den verlinkten thread. Und dann habe ich versucht, eine kleine " proof-of-concept-code:

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());
        }
    }
}

Funktioniert es perfekt:-)

Aber mit der admin.exe es nicht funktioniert? Die admin.exe keine schwierig-input-Methode, und es braucht keine eingegebene Passwort.

Ich weiß, die admin.exe ist in c geschrieben und kompiliert mit mingw unter linux. So habe ich ein kleines dummy-tool:

#include <stdio.h>

int main() {
        int readed;
        while ((readed = fgetc(stdin)) >= 0)
                fputc((char)readed, stdout);
}

Dieses tool macht nur das echo der eingegebene text/Linie. Ich erstellte es mit i586-mingw32msvc-gcc und kopiert es auf meinem windows-Rechner. Dort verwendete ich das Programm auf der Spitze von diesem post für die Kommunikation mit der dummy.exe. Es funktioniert nicht. Kein echo angezeigt wird. Aber warum?

Den ich kompiliert habe, die dummy-code auch mit dem Microsoft C++ Compiler, gleiche Wirkung.

Update2

(btw: vielen Dank an Tim Post)

Bin ich versucht und versucht. Ich habe versucht, erstellen Sie ein c-Tool, die nicht die gleiche wie mein c# - tool. Ich verwendet _popen, aber der Effekt war, dass der Ausgang gezeigt wurden, die am Ende des Prozesses. Hm, nicht gut.

Fand ich diese alternative-Befehls-shell für windows:

https://stackoverflow.com/questions/440269/whats-a-good-alternative-windows-console

http://sourceforge.net/projects/console/

Scheint es zu funktionieren. Es wird die stdout/err in Echtzeit, Umleitung der stdin und admin.exe funktioniert. Und es ist opensource. Vielleicht finde ich ja die Lösung in der C++-Code.

Ich bin nicht gut in C++, so ist es schwer, aber ich werde es versuchen. Kann sein das ich zu schreiben, ein "clear" redirect-wrapper in C/C++ und in C#.

Wenn jemand eine Idee hat, bitte sagt es, weil der andere Weg kann sehr hart sein (für mich^^):-)

Dank.

beste Grüße

Update 3

Hm, ich denke, dies geschieht, weil das Kind-Prozess (admin.exe) verwendet ein paar threads...
Aber wie kann man es lösen?

Ich hatte genau das gleiche problem und kam mit einem (etwas notdürftigem) - Lösung finden Sie hier: stackoverflow.com/questions/6655613/... . Ich glaube, die haben einen link zu einer .REIßVERSCHLUSS mit der vollständigen Lösung.
Einige Programme sind nur Sauer über die Eingabe - /Ausgabe-Umleitung. Admin.exe ist eine starke cue, die es werden wollen, zu Lesen Passwörter aus, die wahre Konsole.
Ich zusammengeführt haben, Ihre nicht registrierten Konten und konvertiert Ihre Antwort als edit zu deiner Frage, bitte prüfen Sie die Richtigkeit. Sie haben jetzt die volle Kontrolle über Ihre Fragen und Antworten.
Vielleicht haben Sie Interesse in diesem post, die deckt viele der Feinheiten arbeiten .NETTO-Prozesse, vor allem rund um die Arbeit mit input und output. Es empfiehlt sich, die MedallionShell - Bibliothek, die vereinfacht den Umgang mit Prozess-io-streams
Was ist, wenn Sie readonce char gleichzeitig? ReadLine wird benötigen drücken Sie die EINGABETASTE. while (true) { p.StandardInput.Schreiben(Konsole.ReadKey()); }

InformationsquelleAutor Stefan Hasler | 2011-08-15

Schreibe einen Kommentar