Entwickler-Ecke
Basistechnologien - Process StandardInput.WriteLine -> Ergebnis abwarten
Trashkid2000 - So 22.01.12 10:39
Titel: Process StandardInput.WriteLine -> Ergebnis abwarten
Hallo,
ich sitze grade an folgendem Problem: Ich möchte gerne einem Process, der von mir gestartet wird, aber die ganze Zeit über läuft, Befehle schicken und dann das Ergebnis abwarten, was in den StandardOutput geschrieben wird, um es dann auszuwerten. Und das ist das Problem :?
Denn ich kann nicht WaitForExit benutzen, da der Process ja nicht beendet wird...
Ok, ich bin zwar in der Lage, asynchron den Output zu lesen, aber das nützt mir ja nichts, da es ja wieder ein eigener Thread ist.
Hoffe, das Problem ist verstänndlich rübergekommen und jemand weiß dafür eine Lösung.
LG und schönen Sonntag,
Kha - So 22.01.12 12:29
Trashkid2000 hat folgendes geschrieben : |
| Ok, ich bin zwar in der Lage, asynchron den Output zu lesen, aber das nützt mir ja nichts, da es ja wieder ein eigener Thread ist. |
Und das ist ein Problem, weil...? Geht es um eine GUI und das richtige Marshalling der Antwort auf den UI-Thread?
Trashkid2000 - So 22.01.12 16:28
Hallo Kha,
erstmal Danke für Deine Antwort. Ups, hatte ich vergessen, dass es sich um eine WPF-Anwendung handelt.
Ich poste einfach mal etwas Code:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
| private StringBuilder outputDataStringBuilder = new StringBuilder(); public string SendCommand(string command) { Process.BeginOutputReadLine(); outputDataStringBuilder.Clear(); Process.StandardInput.WriteLine(command); Process.CancelOutputRead(); return outputDataStringBuilder.ToString(); }
private void OnOutputDataReceived(DataReceivedEventArgs args) { if (!string.IsNullOrEmpty(args.Data)) outputDataStringBuilder.AppendLine(args.Data); }
private void InitializeAndStartProcess() { var startInfo = CreateProcessStartInfo(); Process = new Process() { StartInfo = startInfo }; Process.OutputDataReceived += (x, y) => { OnOutputDataReceived(y); }; Process.Start(); } |
So, also der Process, hier als schlechtes Beispiel die cmd.exe, wird also einmal gestartet. Nun soll über die Methode "SendCommand" z.B. der Befehl dir abgesetzt werden. Und diese Methode soll also so lange warten, bis die cmd alles in den Output geschrieben hat. Und den Output dann zurückgeben. Naja, und nun kehrt also meine Methode sofort zurück (mit einem leeren string), und im Hintergrund wird danach alles schön in den StringBuilder geschrieben.
Ich weiß nicht, wie ich das gebacken kriege, dass ich so lange warte...
Ralf Jansen - So 22.01.12 16:47
| Zitat: |
| bis die cmd alles in den Output geschrieben hat. |
Wenn das Prozess Ende nicht das Ende des in den Output schreiben markiert was dann? Ein spezieller Text der im Output auftaucht? Dann könnte man den Thread eventuell mit einem
AutoResetEvent [
http://msdn.microsoft.com/de-de/library/system.threading.autoresetevent.aspx] warten lassen und durch einen entsprechenden Prüfcode in OnOutputDataReceived irgendwann freischalten.
Trashkid2000 - So 22.01.12 17:57
Hmm, stimmt schon.
Irgendwie muss ich den Kram ja eh parsen... aber ich wollte die "SendCommand" so allgemeingültig wie möglich gestalten, und dort nicht irgendeine große Logik wie das Parsen des OutputStreams machen. Das sollte dann an einer anderen Stelle passieren. Dachte, dass es da irgendeinen Marker gibt, der sagt "so, ich bin nun fertig". Aber anscheinend nicht.
Vielen Dank auf jeden Fall!
Trashkid2000 - So 22.01.12 20:23
Hi,
auch wenn ich immer noch an einer Lösung interessiert bin...
Ein Kumpel (für den ich das programmieren soll) meinte gerade, dass sich der Process nach einem Befehl immer beendet. Damit besteht das Problem also nicht mehr, da ich darauf reagieren kann.
Vielen Dank auf jenden Fall an denen, die versucht haben, mir zu helfen!
LG
C# - So 22.01.12 20:30
Hey Trashkid,
warum willst du das lesen des Outputs überhaupt asynchron machen wenn du sowieso warten willst? Erledige die Ganze Prozedur doch mit ReadToEnd() dann haste ja deinen kompletten Output. Wenn das nicht geht kannste ja in einer Schleife prüfen, ob was neues dazugekommen ist oder nicht. Und wenn nichts neues dazu gekommen ist kannste ja aus der Schleife springen und dann returnen.
Kha - So 22.01.12 21:07
Trashkid2000 hat folgendes geschrieben : |
| auch wenn ich immer noch an einer Lösung interessiert bin... |
Die hat Ralf Jansen doch schon genannt :) : Wenn du die zwei Threads synchronisieren willst, brauchst du eine Art Mutex, z.B. eben ein AutoResetEvent. Etwas moderner (vielleicht bei dir sogar angemessener wegen GUI?) als einfach in der Methode zu blocken wäre wahrscheinlich aber die Rückgabe eines
Task<string>, sollte sich mit einer
TaskCompletionSource implementieren lassen (oder für Bonuspunkte über die Reactive Extensions).
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!