Der Code sieht fast so aus: Wie Sie sehen können, startet der Code einen cmd. exe-Prozess und übergibt an ihn den Befehl, den ich ausführen möchte. Ich umleiten StandardError und StandarOutput, um sie aus dem Code zu lesen. Der Code liest sie vor dem Prozess. WaitForExit (Timeout), wie von Microsoft empfohlen (mehr dazu später). Das Problem tritt auf, wenn der Befehl, den ich an cmd. exe sendet, niemals endet oder hängt unbegrenzt. Im Code verwendete ich den Befehl ping - t 8.8.8.8, der wegen der Option - t den Host ohne Stopp pingt. Was passiert Der cmd. exe-Prozess zusammen mit dem Befehl ping - txt wird nie beendet und schliesst den stdout-Stream nicht, und so hängt unser Code an der Ausgabe process. StandardOutput. ReadToEnd () Zeile, weil es nicht gelingt, den gesamten Stream zu lesen. Das gleiche passiert auch, wenn ein Befehl in einer Batch-Datei aus irgendeinem Grund hängt und so der obige Code könnte kontinuierlich arbeiten für Jahre und dann hängen plötzlich ohne ersichtlichen Grund. Bevor ich schrieb, dass es empfohlen, um umgeleitete Streams vor dem Prozess lesen. WaitForExit (Timeout) Aufruf, auch dies gilt insbesondere, wenn Sie die WaitForExit Signatur ohne das Timeout verwenden. Wenn Sie Prozess aufrufen. WaitForExit (), bevor Sie die umgeleiteten Datenströme lesen: code 2: Sie können einen Deadlock erleben, wenn der Befehl, den Sie an cmd. exe anhängen, oder der Prozess, den Sie aufrufen, die Standardausgabe oder Standardfehler erfüllt. Dies, weil unsere Code cant erreichen die Linien Output-Prozess. Standardausgang. ReadToEnd () In der Tat der Kind-Prozess (die Ping-Befehl oder eine Batch-Datei oder was auch immer Sie ausführen) cant gehen auf, wenn unser Programm nicht lesen Sie die gefüllten Puffer der Streams und dies kann passieren, weil der Code hängt Die Linie mit Prozess. WaitForExit (), die immer warten wird, bis das untergeordnete Projekt beendet wird. Die Standardgröße beider Streams beträgt 4096 Byte. Sie können diese beiden Größen mit diesen Batchdateien testen: Das erste Skript schreibt 4096 Byte zur Standardausgabe und das zweite zu Standardfehler. Speichern Sie eine davon in C: testbuffsize. bat und führen Sie unseren Programmaufruf aus. WaitForExit () vor Ausgabeprozess. Standardausgang. ReadToEnd () wie in Code 2. Können Sie es Schreiben CommandResult Ergebnis ExecuteShellCommandSync (c: testbuffsize. bat, 1000) in Zeile 13 von Code 1. Der Code wird nicht hängen, aber wenn Sie schreiben ein weiteres Byte in einem der beiden Streams wird es überlaufen die Puffergröße, die das Programm aufhängen. Wenn Sie die Standardausgabe oder Standardfehler umleiten und lesen müssen, ist die beste Lösung, sie asynchron zu lesen. Eine hervorragende Möglichkeit, dies zu tun, wird von Mark Byers in diesem Stackoverflow-Thread vorgeschlagen Als das letzte, beachten Sie bitte, dass, wenn der untergeordnete Prozess beendet, nur weil Sie den Prozess verwenden. WaitForExit (Timeout) Signatur und es tatsächlich geht in Timeout sollten Sie töten die cmd. exe Prozess und seine möglichen Kinder. Ich habe eine App, die einen anderen Prozess in einem Befehlsfenster aufruft und dieser Prozess hat die Aktualisierung der Statistiken, die Ausgabe an die Konsole Fenster. Ich dachte, dies war eine ziemlich einfache Operation, aber ich kann nicht scheinen, um es an die Arbeit. Bin ich etwas fehlt Im Idealfall, was ich möchte, ist, wie die Ausgabe ändert sich innerhalb dieses Prozesses schlage ich oder Daten kommt in den Leser, dass ich Ereignisse ausgeschaltet es. Jede mögliche Hilfe würde groß sein, ich fühle mich wie dieses ist eine Neulingfrage aber scheinen, etwas zu vermissen. Gefragt Jul 17 09 at 22:33 Ive erlebt dies vor. Manchmal ist die Art und Weise, in der der Prozess, den Sie die Ausgänge auf die Konsole aufrufen, nicht mit dieser Art von Ausgabeumleitung kompatibel. Ive gewesen glücklich genug in diesem Fall in der Lage sein, den externen Prozess zu ändern, um dies zu ändern. Sie könnten versuchen, Ihren Code auf einem anderen Prozess auszuführen, der an die Konsole ausgibt, und sehen, ob es ordnungsgemäß funktioniert. Es liest ungefähr Recht zu mir gerade jetzt. Ich ging und zog ein Code-Block Ive verwendet, um dies zu tun. Dies ist in einer WPF-App, die die Prozessausgabe an das Fenster umleitet. Beachten Sie die Ereignisbindung. Da dies WPF ist, muss ich meinen Aufruf aufrufen, um die Daten zu schreiben. Da Sie Arent besorgt über Blockierung, sollten Sie in der Lage, einfach zu ersetzen, dass mit: Hoffentlich hilft es Interessant können Sie nicht aus Standard-Ausgabe und Standard-Fehler zur gleichen Zeit lesen: wenn Sie sowohl Standard-Ausgabe und Standard-Fehler umleiten und dann versuchen, beide zu lesen , Beispielsweise unter Verwendung des folgenden C-Codes. String-Ausgabe p. StandardOutput. ReadToEnd () String-Fehler p. StandardError. ReadToEnd () In diesem Fall, wenn der untergeordnete Prozess einen beliebigen Text auf Standardfehler schreibt, wird es den Prozess blockieren, da der übergeordnete Prozess nicht vom Standardfehler lesen kann, bis er hat Fertig ausgelesen. Der übergeordnete Prozess wird jedoch nicht von der Standardausgabe gelesen, bis der Prozess beendet ist. Eine empfohlene Lösung für diese Situation besteht darin, zwei Threads zu erstellen, damit Ihre Anwendung die Ausgabe jedes Streams auf einem separaten Thread lesen kann. Lesen Sie, was MSDN darüber sagt: Die WaitForExit () () () - Überladung wird verwendet, um den Strom zu erzeugen Warten, bis der zugehörige Prozess beendet wird. Diese Methode weist die Prozesskomponente an, eine unbegrenzte Zeitspanne zu warten, bis der Prozess beendet wird. Dies kann dazu führen, dass eine Anwendung nicht mehr reagiert. Wenn Sie beispielsweise CloseMainWindow für einen Prozess aufrufen, der über eine Benutzeroberfläche verfügt, wird die Anforderung des Betriebssystems, den zugeordneten Prozess zu beenden, möglicherweise nicht bearbeitet, wenn der Prozess geschrieben wird, um niemals in seine Nachrichtenschleife zu gelangen. Diese Überlastung stellt sicher, dass alle Verarbeitung abgeschlossen ist, einschließlich der Handhabung von asynchronen Ereignissen für die umgeleitete Standardausgabe. Sie sollten diese Überladung nach einem Aufruf der WaitForExit (Int32) - Uberladung verwenden, wenn die Standardausgabe auf asynchrone Ereignisbehandlungsroutinen umgeleitet wurde. Das ist natürlich für. NET. Was macht Sie denken, dass es nicht warten, bis die Note-Prozess zu beenden Was sind die Anzeichen dafür, was ist der Beweis Freitag, Februar 20, 2009 8.13 PM Nicht sicher, ob dies kürzlich geändert hat, aber zurück in den Tag Anwendungen auf Fenster Handy nie wirklich geschlossen, wenn Sie die X schließe sie zu schließen, würden sie nur minimieren und halten im Hintergrund laufen (dies war kein Fehler, es war ein Feature, da das nächste Mal starten Sie die App würde es wirklich schnell gestartet werden, yah Ich weiß, wahnsinnig, aber wahr), so könnte das sein, warum WaitForExit ist vielleicht seltsam verhalten und warten auf App-Start anstelle von Exit. Aber dann ist es nur Spekulation auf knowlegde der alten Versionen von Windows Mobile basiert. Freitag, den 20. Februar 2009 um 11:03 Uhr Id wie zu stoßen diese Frage auf. Im auf Windows Mobile 6 Standard und Im versuchen, eine Browser-Instanz spawn. Id wie zu warten, bis der Benutzer den Browser schließt. Aber WaitForExit kommt extrem schnell zurück. Hier ist der Code: Process p new Process () p. StartInfo. Argumente quotexample-sitequot p. StartInfo. Verb quotOpenquot p. StartInfo. UseShellExecute false p. StartInfo. FileName quotIExplore. exequot p. Start () p. WaitForExit () MessageBox. Show (quotNow der Browser sollte closedquot sein) Was sollte der richtige Weg, um die erwarteten Resuts erhalten werden, wo das Symbol ist. Symbol. AlexB Dienstag, 9. Juni 2009 09:58 Ich sehe das gleiche Problem, aber auf XP. Ich denke, der Beweis kann in jedem Debugger gesehen werden (wie ich sehe), oder in jeder Konsolenanwendung (nicht unbedingt auf Mobile) Mittwoch, 2. September 2009 8.35 Uhr Außer, dass Sie nicht erhalten dann ein Prozess-Objekt, das Sie können benutzen. MyProc. WaitForExit () Es ist immer noch unverzüglich zurückgegeben, wenn Sie versuchen, Dim myProc als neuen Prozess () myProc Process. Start (quotiexplorequot, quotfinance. yahoo/q/hpsquot Symbol) Mittwoch, 2. September 2009 20.48 Uhr Problem ist, dass Sie nicht eine neue Instanz von iexplore. exe starten. Sie erstellen lediglich ein neues Fenster zum bestehenden Prozess. Meine Vermutung ist, iexplore. exe startet, sieht eine vorhergehende Instanz und kommuniziert mit der vorherigen Instanz, so dass es das neue Fenster öffnet, und dann diese Instanz, die Sie sofort beendet verlassen. Das Verhalten ist also richtig und zu erwarten. Blog. voidnish Mittwoch, den 2. September 2009 um 20:52 Uhr Microsoft führt eine Online-Umfrage durch, um Ihre Meinung über die Msdn-Website zu verstehen. Wenn Sie sich für eine Teilnahme entscheiden, wird Ihnen die Online-Umfrage präsentiert, wenn Sie die Msdn-Website verlassen. Möchten Sie teilnehmen
No comments:
Post a Comment