Laden...

Dos-Konsole ständig auslesen

Erstellt von Nightfall1981 vor 16 Jahren Letzter Beitrag vor 16 Jahren 3.103 Views
N
Nightfall1981 Themenstarter:in
12 Beiträge seit 2006
vor 16 Jahren
Dos-Konsole ständig auslesen

Hallo,

also ich hab da mal eine Frage, auf die ich auch mit der Forensuche kein richtiges Ergebnis gefunden habe. Oder ich hab es übersehen. Jedenfalls habe ich ein externes Programm (COSIMA) das eine Konsolenanwendung ist. Den Quellcode für dieses Programm habe ich nicht. Nun möchte ich eine Grafische Oberfläche drauf packen, jedoch wie gesagt ohne den Quellcode zu haben. Sprich ich möchte das Programm von meiner Form aus Starten. Nun ist es so. dass COSIMA ständig irgendwelche Werte und Fortschritte und so in der Dos Konsole ausgibt. Was ich jetzt möchte, ist, dass die Konsole 1. nicht geöffnet wird, und dass 2. die Ausgaben in der Konsole Abgefangen und in einer Textbox in meiner Form ausgegeben werden sollen.

Also hier meine Frage: Ist das Möglich? Und wenn ja, wie? Also, wie fange ich die Ausgaben der Konsole ab und gebe sie in einer Textbox aus?

Ich hoff mal hier kann mir geholfen werden ^^

D
386 Beiträge seit 2007
vor 16 Jahren

Die Process Klasse kann die Standardausgabe umlenken, d.h. du kannst die Standardausgabe eines Prozesses lesen. Dort, in den StartInfo Einstellungen des Prozesses, kannst du auch dafuer sorgen dass keine Konsole aufgeht.

Auch wenn das immer wieder auftaucht: Das ist keine DOS Box.. Ausser du benutzt Windows 1.x, 3.x, 95, 98 oder ME.

Pound for pound, plutonium is about as toxic as caffeine when eaten.

N
Nightfall1981 Themenstarter:in
12 Beiträge seit 2006
vor 16 Jahren

Oh... also ich hab es jetzt genau so versucht, leider stürzt mir mein Zielprogramm ab, sobald ich UseShellExecute = false; hab. Woran kann das liegen? Liegt da ein Fehler am Zielprogramm vor?

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo Nightfall1981,

ich vermute, der Absturz ist eine Auswirkung von:

Die WorkingDirectory-Eigenschaften weist, wenn UseShellExecute den Wert true hat oder wenn UseShellExecute den Wert false hat, unterschiedliches Verhalten auf. Wenn UseShellExecute den Wert true hat, gibt die WorkingDirectory-Eigenschaft den Speicherort der ausführbaren Datei an. Wenn WorkingDirectory eine leere Zeichenfolge ist, wird angenommen, dass sich die ausführbare Datei im aktuellen Verzeichnis befindet.

Dadurch findet das gestartete Programm womöglich irgendwelche Dateien, die es benötigt, nicht.

herbivore

N
Nightfall1981 Themenstarter:in
12 Beiträge seit 2006
vor 16 Jahren

Hm kann ich irgendwas dagegen tun? Also mit UseShellExecute = true; und ohne WorkingDirectory kommt von dem Programm ne Fehlermeldung, dass eine Konfigurationsdatei nicht gefunden wurde. Wenn ich das WorkingDirectory setze und UseShellExecute = true; hab lässt sich das Programm problemlos starten, aber eben in der Konsole. Wenn ich dann UseShellExecute = false; setze stürzt das gestartete Programm eben ab und will nen Fehlerbericht senden.

Edit: Wenn ich WorkingDirectory rausnehm stürzt mein Programm zwar nicht mehr mit Fehlerbericht und so ab, dafür öffnet sich nur für Sekundenbruchteile ein Konsolenfenster. Und mstring Output = Process.StandardOutput.ReadToEnd(); bringt dann den Fehler, dass die Standartausgabe nicht umgeleitet wurde (wurde sie aber!) oder der Prozess nicht gestartet wurde. Das heißt wohl mein Zielprogramm wird sofort wieder geschlossen.

D
40 Beiträge seit 2006
vor 16 Jahren

Setz das WorkingDirectory und UseShellExecute = true und den WindowStyle auf Hidden.

Ja du hast was übersehen. 😉

Hier gibts Infos, zu deinem Problem:
[Tutorial] Prozess/Anwendung aus eigenem Programm starten

Eine weitere Möglichkeit wäre z.B. Start Informationen für eine Anendung vor dem Starten auszurufen, wo es beim Aufrufen von Konsolenprogrammen die nur etwas ausführen sollen die schöne Eigenschaft zu verstecken der Konsole gibt, was ein aufblitzen eines Konsolenfensters verhindert. Ein gerne von mir verwendetes Beispiel ist das Folgende:

  
// "net send" wird aufgerufen um eine Nachricht zu versenden  
System.Diagnostics.ProcessStartInfo sendInfo = new System.Diagnostics.ProcessStartInfo("net.exe","send \"" + empfaenger + "\" \"" + sendText + "\"");  
// Fenster des zu startenden Prozesses wird versteckt  
sendInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;  
// Warte mit der Programmausführung bis der Prozess beendet ist  
System.Diagnostics.Process.Start(sendInfo).WaitForExit();  
  
N
Nightfall1981 Themenstarter:in
12 Beiträge seit 2006
vor 16 Jahren

Aber wenn UseShellExecute = true ist kann ich doch keine Umleitung des IO-Streams aktivieren, oder seh ich da was falsch?

Edit: Hab es jetzt soweit hinbekommen, dass mein externes Programm gestartet wird und mein StandartOutput auch einige Zeilen liest. Dann allerdings wird (bei separater Ausführung von Cosima) folgende Zeile von Cosima ausgeben:

Wollen Sie Cosima jetzt lizensieren? <j/n>

Am Ende der Zeile scheint Cosima auf eine Eingabe zu warten. Das dumme ist, dass diese Zeile überhaupt nicht in meinem Standartoutput erscheint und mein Programm irgendwie ewig drauf wartet die Zeile zu ende lesen zu können. Was kann ich denn jetzt machen?

B
1.529 Beiträge seit 2006
vor 16 Jahren

Möglicherweise erfolgt die Ausgabe über StandardError?

N
Nightfall1981 Themenstarter:in
12 Beiträge seit 2006
vor 16 Jahren

Das Problem ist, dass das Programm bei der Einzelschrittausführung beim Auslesen dieser Zeile mit ReadLine hängen bleibt. Also irgendwie liest es sich zu Tode. Das einzige was ich tun kann ist den Debug Prozess abzubrechen. Genau wie bei einer Endlosschleife.

B
1.529 Beiträge seit 2006
vor 16 Jahren

Das erscheint mir logisch. Da das Programm auf eine Eingabe wartet, schreibt es den Text ohne Zeilenende. Wenn du mit Sicherheit weißt, dass diese Abfrage kommt, kannst du ja einfach ein n senden...

N
Nightfall1981 Themenstarter:in
12 Beiträge seit 2006
vor 16 Jahren

Das Problem ist ich muss diese Abfrage abfangen. Es ist die Frage nach Lizenzierung des Programms. Und natürlich kommt sie nur, wenn das Programm keine Lizenz hat 😦

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo Nightfall1981,

es kann aber gut sein, dass du nicht an die Frage kommst, sondern dass sie im Puffer stecken bleibt und erst übertragen wird, wenn der Puffer voll ist, was er ja aber nicht wird, weil das Programm bei der Frage hängt. Wenn das Programm keine anderen Fragen stellt und keine anderen Eingaben erfordert, dann beantworte die Frage einfach, ob sie gestellt wird oder nicht.

herbivore

N
Nightfall1981 Themenstarter:in
12 Beiträge seit 2006
vor 16 Jahren

Hm dann würde ich aber die Lizenzierung unterbinden. Wie kann ich dem dann entgegen wirken? Oder gibt es da keine Möglichkeit? Kann ich statt ReadLine vlt. nur eine bestimmte anzahl an Zeichen an dieser Stelle abfragen? Oder gibt es eine Möglichkeit bei ReadLine ein TimeOut zu setzen?

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo Nightfall1981,

meines Wissens kommt man an den Puffer nicht ran.

herbivore

N
Nightfall1981 Themenstarter:in
12 Beiträge seit 2006
vor 16 Jahren

Ich versuche jetzt mit p2.StandardInput.Write('n'); die Abfrage zu beantworten. Aber jetzt wird der Prozess davon beendet und zwar schon vor der Abfrage.

Edit: Okay ich habs geschafft. Jetzt ne andere Frage. Wie kann ich das was ich in meinen String Output einlese sofort wieder in meiner Textbox ausgeben? Also das soll natürlich während der Ausfürung des Prozesses gleich ausgegeben werden. Ist das überhaupt möglich?

N
Nightfall1981 Themenstarter:in
12 Beiträge seit 2006
vor 16 Jahren

Bitte entschuldigt den Doppelpost. Aber wenn ich meinen Beitrag nur editiere merkt ja keiner dass da was neu ist. Ihr solltet mal nen entsprechnenden Hack einbauen ^^

Also es sieht jetzt folgendermaßen aus, das Externe Programm wird endlich brav ausgeführt. Den Puffer ignorier ich einfach indem ich ne eigene Abfrage davor eingebaut hab und ihm entsprechend j oder n sende . Soweit so gut. Es gibt auch brav in meinem Output String die Outputs aus. Aber wie um alles in der Welt gebe ich denn jetzt meinen Output String in meiner Textbox aus? Und das noch während der Prozess ausgelesen wird? Das Externe Programm läuft schon mal gut ne Stunde oder so und ich will währenddessen natürlich die ganzen Outputs die es macht in meiner Form sehen. Und der Button soll dann solange gesperrt sein. Ich habe aber beim besten willen nicht den blassesten Schimmer wie ich das alles anstellen soll. Sowas hab ich einfach noch nie gemacht und bisher auch nie gebraucht. Kann mir hier irgendjemand sagen wie ich das machen muss?

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo Nightfall1981,

anzeigen kannst du einen String, indem du ihn an textBox1.Text zuweist. Wenn das keine Wirkung zeigt oder Probleme macht, würde ich auf [FAQ] Warum blockiert mein GUI? oder [FAQ] Controls von Thread aktualisieren lassen (Control.Invoke) tippen. Um zu verhindert, dass während der Laufzeit des Programmes der Button erneut gedrückt wird, setze button1.Enabled = false.

herbivore

PS: Den "Hack" gibt es ja schon. 🙂 Nämlich einen neuen Beitrag posten, statt zu editieren, wenn zwischen den beiden Aktionen zuviel Zeit liegt, wie du es nun gemacht hast. Diese Vorgehensweise ist vollkommen ok.