Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
externes Consolen Programm starten und steuern
Krumnix
myCSharp.de - Member



Dabei seit:
Beiträge: 124
Herkunft: Schweiz

Themenstarter:

externes Consolen Programm starten und steuern

beantworten | zitieren | melden

Hallo.
Habe ein Konsolen Programm, welches zu einer Robotersteuerung die Verdingung aufbaut und man Daten austauschen kann.
Nun würde ich gerne den Ablauf zur Inbetriebnahme des Roboters automatisieren. Sprich, die im Moment alle händisch eingetippten Befehle durch ein C# Programm nach und in die Konsole übergeben.
Das K-Programm starten ist kein Problem. Es zu verstecken und so auch.
Nun zu meinem Probleme, bzw. wo ich im Moment hänge:

1.
Mit

BatchProcess.StartInfo.RedirectStandardOutput = true;
                BatchProcess.StartInfo.RedirectStandardInput = true;
steuere ich ja die Möglichkeit, die Ausgabe umzuleiten, bzw. die Eingabe.
Da nach dem Starten des Konsolen Programms hier eine Eingabe gewartet wird, "hängt" mein Programm in der Zeile:

textBox_Output.Text = textBox_Output.Text + BatchProcess.StandardOutput.Read();

Wie kann ich die Ausgabe abfangen ohne dass mein Programm hängen bleibt, da die Konsole eine Eingabe erwartet?

2.
Mit

BatchProcess.StandardInput.Write("cd");
würde ich gerne die Befehle in die Konsole geben.
Weiß jetzt nicht, ob es an Problem 1 liegt, dass es nicht weiter funktioniert, oder ob ich was falsch mache?

Jemand einen Tipp für mich?
Danke!
private Nachricht | Beiträge des Benutzers
Th69
myCSharp.de - Experte

Avatar #avatar-2578.jpg


Dabei seit:
Beiträge: 4193

beantworten | zitieren | melden

Läuft dein Code bisher synchron, d.h. die textBox_Output.Text-Teile hast du direkt nach dem Starten des Prozesses in demselben Thread aufgerufen?

Dann sollte dir das Process.OutputDataReceived-Ereignis weiterhelfen (beachte auch BeginOutputReadLine()).
So kannst du dann die Eingaben senden und asynchron die Ausgabe verarbeiten (wohl mittels [FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke)).
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Th69 am .
private Nachricht | Beiträge des Benutzers
MarsStein
myCSharp.de - Experte

Avatar #avatar-3191.gif


Dabei seit:
Beiträge: 3430
Herkunft: Trier -> München

beantworten | zitieren | melden

Hallo,

zusätzlich solltest Du am Ende eines Befehls einen Zeilenumbruch (Environment.NewLine) am Ende mitschicken, denn auf der Konsole wird der Befehl ja auch für gewöhnlich erst durch das Drücken der Enter-Taste ausgelöst.

Gruß, MarsStein
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von MarsStein am .
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
private Nachricht | Beiträge des Benutzers
Krumnix
myCSharp.de - Member



Dabei seit:
Beiträge: 124
Herkunft: Schweiz

Themenstarter:

beantworten | zitieren | melden

Die TextBox hab ich rausgeworfen.

Hab aktuell folgenden Code drin:

Process process = new Process();
                process.StartInfo.FileName = CmdCall;
                process.StartInfo.Arguments = " -i" + IPAddress + " \"VERSION\" ";
                process.StartInfo.UseShellExecute = false;
                process.StartInfo.RedirectStandardOutput = true;
                process.StartInfo.RedirectStandardError = true;
                process.OutputDataReceived += new DataReceivedEventHandler((sender, e) =>
                {
                    // Prepend line numbers to each line of the output.
                    if (!string.IsNullOrEmpty(e.Data))
                    {
                        output_console = output_console + "\n" + e.Data;
                    }
                });
                process.ErrorDataReceived += new DataReceivedEventHandler((sender, e) =>
                {
                    // Prepend line numbers to each line of the output.
                    if (!string.IsNullOrEmpty(e.Data))
                    {
                        output_console = output_console + "\n" + e.Data;
                    }
                });
                process.StartInfo.CreateNoWindow = true;
                process.Start();

                process.BeginOutputReadLine();
                process.BeginErrorReadLine();

In meinem output_console string steht nix drin.
Lustigerweise jedoch im Ausgabe-Fenster von VS2017.
Was mache ich falsch? Wie bekomme ich die Daten in den String?
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Krumnix am .
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 16223

beantworten | zitieren | melden

Du kannst doch selbst mit dem Debugger schauen, warum das so ist.
[Artikel] Debugger: Wie verwende ich den von Visual Studio?
- performance is a feature -

Microsoft MVP - @Website - @blog - @AzureStuttgart - github.com/BenjaminAbt
private Nachricht | Beiträge des Benutzers
Krumnix
myCSharp.de - Member



Dabei seit:
Beiträge: 124
Herkunft: Schweiz

Themenstarter:

beantworten | zitieren | melden

Ja, sicher weiß ich das. Macht mich aber nicht schlauer.
Mit dem DataReceivedEventHandler erhalte ich wohl jede Änderung in der Console und schreibe dies dann in den String.

Mit BeginOutputReadline stoße ich dies wohl an.

Wenn ich nun mit F11 durchschalte, dann wird erst beim Schließen meiner Anwendung in den String geschrieben, obwohl schon vorher die Console geschlossen ist.

Warum also schreibt er erst beim Beenden des Programms in den String und nicht beim Schließen des Consolenfensters?
private Nachricht | Beiträge des Benutzers
T-Virus
myCSharp.de - Member



Dabei seit:
Beiträge: 1919
Herkunft: Nordhausen, Nörten-Hardenberg

beantworten | zitieren | melden

Wie sollen wir dir das sagen können ohne deinen Code zu kennen?
Wo wird dann der String überall verwendet?
Wenn nur in den beiden Events, dann vermutlich weil diese erst am Ende gefeuert werden.
Ansonsten an jeder Stelle, die keiner hier einsehen kann.

Mit dem Debugger wäre dies aber am einfachsten zu prüfen.

Nachtrag:
In der Doku steht übrigens auch der hinweis WaitForExit aufzurufen, damit die Ausgabepuffer geleert werden.
Erst dann dürften auch die Events korrekt gefeuert werden.

Nachtrag 2:
Ebenfalls solltest du, wenn es viele Ausgaben gibt, nicht mit String arbeiten.
Nimm hier lieber, wie im Doku Beispiel, einen StringBuilder.
Sonst wirst du mit viel Speicher um dich, wenn dort viele Ausgaben passieren.

Nachtrag 3:
Ebenfalls solltest du für beide Events eine eigene Methode auslagern.
Da beide Events die gleiche Signatur haben, wird somit kein Code unnötig dubliziert.
Ebenfalls kann man sich leicht durch anonyme Event Methoden ein Speicherloch bauen, wenn man dort Objekte von außen reingibt.

T-Virus
Dieser Beitrag wurde 3 mal editiert, zum letzten Mal von T-Virus am .
Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.
private Nachricht | Beiträge des Benutzers
Krumnix
myCSharp.de - Member



Dabei seit:
Beiträge: 124
Herkunft: Schweiz

Themenstarter:

beantworten | zitieren | melden

Danke erstmal für eure Hilfen.

Der string war vorher auch ein stringbuilder. Beides hatte keine Auswirkung.
process.WaitForExit füllte den string auch nicht.

Im Grunde erhalte ich ja was, aber nur im Ausgabe-Fenster in VS nicht in meinen String rein.

Die beiden Events habe ich erstmal für mein Verständnis aufzubauen aus dem Beispiel im Link so verwendet.
Schieb die mal in eine eigene Methode. Melde mich dann wieder.
Danke
private Nachricht | Beiträge des Benutzers
Th69
myCSharp.de - Experte

Avatar #avatar-2578.jpg


Dabei seit:
Beiträge: 4193

beantworten | zitieren | melden

Funktioniert es denn, wenn du das Programm außerhalb vom VS startest?
Der VS-Debugger lenkt die Ausgabe extra in das Ausgabe-Fenster zusätzlich um, damit der Entwickler mehr Informationen erhält (z.B. sinnvoll bei GUI-Projekten mit Debug-Konsolenausgaben).
private Nachricht | Beiträge des Benutzers