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?
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
Du musst angemeldet sein, um einen Kommentar abzugeben.
Das problem könnte, weil Sie mit
Readline
, wo die Daten ausgegeben werden vonadmin.exe
Anwendung werden sequentiell und nicht in neue Zeilen.., versuchen zu verwendenRead
statt, und bauen die wünschenswert string aus..Auch Sie müssen nicht auf
Environment.NewLine
zu schreiben, Zeichenfolge, gefolgt von neue Zeile verwendenWriteLine
statt, so:Ja, ich bezog mich auf
BeginOutputReadLine
und so diee.Data
imOutputDataReceived
werden nur Zeilen gelesen, ich denke, dass das gleiche auch fürBeginErrorReadLine
hier..Sie müssen UseShellExecute auf true für das Verb respektiert werden und es muss auf "false" umleiten der Standardausgabe. Sie können nicht beides tun. Ich bin mir ziemlich sicher, dass Windows auch nicht zulassen, dass Sie zum umleiten von standard-input/output/error über den admin/non-admin Sicherheitsgrenze. Sie müssen einen anderen Weg finden um Ausgabe aus dem Programm als admin ausgeführt - Referenz: stackoverflow.com/a/8690661
InformationsquelleAutor Jalal Said