none
Konsole(CMD) auslesen RRS feed

  • Frage

  • Hallo,

    Ich möchte den Text einer Konsole auslesen. Wie hier gezeigt: http://msdn.microsoft.com/de-de/library/bb979134.aspx
    Ich würde mich über ein Beispiel freuen. Hab schon vieles über die In/Output streams gelesen, nur werde ich nicht wirklich schlau daraus.

    Danke schonmal.
    Mittwoch, 26. August 2009 09:35

Antworten

  • Hallo,

    du hättest das meiste aus dem CodeProject Beispiel übernehmen können.

    Im übrigen braucht man zur Dienstkontolle nicht NET.EXE zu verwenden,
    das geht einfacher über die  ServiceController Klasse.

    Ich habe Deinen Anfang trotzdem komplettiert, falls Du anders damit vorhast:
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Drawing;
    using System.Globalization;
    using System.IO;
    using System.ServiceProcess;
    using System.Text;
    using System.Windows.Forms;
    
    namespace CS2008.Forms
    {
        public partial class RedirectForm : Form
        {
            public RedirectForm()
            {
                InitializeComponent();
    
                // Ermitteln aller Dienste
                this.comboBox1.Items.AddRange(GetServiceNames());
            }
    
            private void Net(string befehl, string dienst)
            {
                ProcessStartInfo startInfo = new ProcessStartInfo();
                startInfo.FileName = System.IO.Path.Combine(
                    Environment.GetFolderPath(Environment.SpecialFolder.System),
                    "Net.exe");
                startInfo.Arguments = befehl + " " + dienst;
                startInfo.UseShellExecute = false;
                startInfo.CreateNoWindow = true;
                startInfo.RedirectStandardInput = false;
                startInfo.RedirectStandardOutput = true;
                startInfo.RedirectStandardError = true;
                // OEM Zeichensatz für NET.EXE
                startInfo.StandardOutputEncoding = GetOemEncoding();
                startInfo.StandardErrorEncoding = GetOemEncoding();
    
                StreamReader outputReader = null;
                StreamReader errorReader = null;
                try
                {
                    this.Enabled = false;
    
                    Process process = Process.Start(startInfo);
                    outputReader = process.StandardOutput;
                    errorReader = process.StandardError;
    
                    string outputText = outputReader.ReadToEnd();
                    string errorText = errorReader.ReadToEnd();
    
                    // Ist hier eine RichTextBox damit es bunter werden kann...
                    this.redirectTextBox.Clear();
                    if (!string.IsNullOrEmpty(outputText))
                    {
    
                        this.redirectTextBox.SelectionColor = Color.Blue;
                        this.redirectTextBox.SelectedText = outputText;
                    }
                    if (!String.IsNullOrEmpty(errorText))
                    {
                        this.redirectTextBox.SelectionColor = Color.Red;
                        this.redirectTextBox.SelectedText = errorText;
                    }
                    process.WaitForExit();
                }
                catch (Exception ex)
                {
                    this.redirectTextBox.SelectionColor = Color.Pink;
                    this.redirectTextBox.Text = "Ausnahme:\r\n" + ex.ToString();
                }
                finally
                {
                    if (outputReader != null)
                        outputReader.Close();
                    if (errorReader != null)
                        errorReader.Close();
                    
                    this.Enabled = true;
                }
            }
    
            private Encoding GetOemEncoding()
            {
                // OEM Zeichensatz ermitteln
                return Encoding.GetEncoding(CultureInfo.CurrentCulture.TextInfo.OEMCodePage);
            }
    
            private string[] GetServiceNames()
            {
    
                List<string> serviceNames = new List<string>();
                try
                {
                    foreach (ServiceController service in ServiceController.GetServices())
                    {
                        serviceNames.Add(service.ServiceName);
                    }
                    serviceNames.Sort();
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("GetServiceNames failed: " + ex.ToString());
                }
                return serviceNames.ToArray();
            }
    
            private void startButton_Click(object sender, EventArgs e)
            {
                string dienst = (Convert.ToString(comboBox1.Text));
                Net("start", dienst);
            }
    
            private void stopButton_Click(object sender, EventArgs e)
            {
                string dienst = (Convert.ToString(comboBox1.Text));
                Net("stop", dienst);
            }
    
            private void resetButton_Click(object sender, EventArgs e)
            {
                string dienst = (Convert.ToString(comboBox1.Text));
                Net("start", dienst);
                Net("continue", dienst);
            }
        }
    }
    
    Gruß Elmar
    Mittwoch, 26. August 2009 19:38

Alle Antworten

  • Hallo,

    fehlen Dir im MSN Beispiel die geschweiften Klammern? ;-)

    Ein vollständiges Beispiel für C# findest Du u. a.
    How to redirect Standard Input/Output of an application

    Gruß Elmar
    Mittwoch, 26. August 2009 10:22
  • Bin einfach noch zu blöd da in C# umzusetzen, mit viel lesen würd ichs vielleicht packen aber hab nicht soviel Zeit. Dank dir, auf englisch hab ich garned gesucht.
    sgeben,
    Habs ned hinbekommen. Seh ich das richtig, dass ich einen neuen Prozess erstellen muss, dessen Eigenschaften definiere und ihm ne Anwendung/File zuweise? Danach die streams weiterleite und diese dan anzeige?

    hier mein script: http://pastebin.com/m1547875e

    Beim Pfeil möchte ich es ausgeben, nur hab ich keine Ahnung wie.
    Mittwoch, 26. August 2009 10:49
  • Hallo,

    du hättest das meiste aus dem CodeProject Beispiel übernehmen können.

    Im übrigen braucht man zur Dienstkontolle nicht NET.EXE zu verwenden,
    das geht einfacher über die  ServiceController Klasse.

    Ich habe Deinen Anfang trotzdem komplettiert, falls Du anders damit vorhast:
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Drawing;
    using System.Globalization;
    using System.IO;
    using System.ServiceProcess;
    using System.Text;
    using System.Windows.Forms;
    
    namespace CS2008.Forms
    {
        public partial class RedirectForm : Form
        {
            public RedirectForm()
            {
                InitializeComponent();
    
                // Ermitteln aller Dienste
                this.comboBox1.Items.AddRange(GetServiceNames());
            }
    
            private void Net(string befehl, string dienst)
            {
                ProcessStartInfo startInfo = new ProcessStartInfo();
                startInfo.FileName = System.IO.Path.Combine(
                    Environment.GetFolderPath(Environment.SpecialFolder.System),
                    "Net.exe");
                startInfo.Arguments = befehl + " " + dienst;
                startInfo.UseShellExecute = false;
                startInfo.CreateNoWindow = true;
                startInfo.RedirectStandardInput = false;
                startInfo.RedirectStandardOutput = true;
                startInfo.RedirectStandardError = true;
                // OEM Zeichensatz für NET.EXE
                startInfo.StandardOutputEncoding = GetOemEncoding();
                startInfo.StandardErrorEncoding = GetOemEncoding();
    
                StreamReader outputReader = null;
                StreamReader errorReader = null;
                try
                {
                    this.Enabled = false;
    
                    Process process = Process.Start(startInfo);
                    outputReader = process.StandardOutput;
                    errorReader = process.StandardError;
    
                    string outputText = outputReader.ReadToEnd();
                    string errorText = errorReader.ReadToEnd();
    
                    // Ist hier eine RichTextBox damit es bunter werden kann...
                    this.redirectTextBox.Clear();
                    if (!string.IsNullOrEmpty(outputText))
                    {
    
                        this.redirectTextBox.SelectionColor = Color.Blue;
                        this.redirectTextBox.SelectedText = outputText;
                    }
                    if (!String.IsNullOrEmpty(errorText))
                    {
                        this.redirectTextBox.SelectionColor = Color.Red;
                        this.redirectTextBox.SelectedText = errorText;
                    }
                    process.WaitForExit();
                }
                catch (Exception ex)
                {
                    this.redirectTextBox.SelectionColor = Color.Pink;
                    this.redirectTextBox.Text = "Ausnahme:\r\n" + ex.ToString();
                }
                finally
                {
                    if (outputReader != null)
                        outputReader.Close();
                    if (errorReader != null)
                        errorReader.Close();
                    
                    this.Enabled = true;
                }
            }
    
            private Encoding GetOemEncoding()
            {
                // OEM Zeichensatz ermitteln
                return Encoding.GetEncoding(CultureInfo.CurrentCulture.TextInfo.OEMCodePage);
            }
    
            private string[] GetServiceNames()
            {
    
                List<string> serviceNames = new List<string>();
                try
                {
                    foreach (ServiceController service in ServiceController.GetServices())
                    {
                        serviceNames.Add(service.ServiceName);
                    }
                    serviceNames.Sort();
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("GetServiceNames failed: " + ex.ToString());
                }
                return serviceNames.ToArray();
            }
    
            private void startButton_Click(object sender, EventArgs e)
            {
                string dienst = (Convert.ToString(comboBox1.Text));
                Net("start", dienst);
            }
    
            private void stopButton_Click(object sender, EventArgs e)
            {
                string dienst = (Convert.ToString(comboBox1.Text));
                Net("stop", dienst);
            }
    
            private void resetButton_Click(object sender, EventArgs e)
            {
                string dienst = (Convert.ToString(comboBox1.Text));
                Net("start", dienst);
                Net("continue", dienst);
            }
        }
    }
    
    Gruß Elmar
    Mittwoch, 26. August 2009 19:38
  • Thanks we got it what we wanted.
    Freitag, 28. August 2009 15:01
  • Hallo Elmar, 

    ich nutze aus diesem Beispiel den Teil mit dem umgeleiteten Output... Jetzt möchte ich jedoch eine TextBox quasi in Echtzeit mit der Ausgabe des aufgerufenen Prozesses füttern. Nach diesem Beispiel wird der Output erst in die Textbox geschrieben, wenn der Prozess beendet wurde. Wie mache ich das jetzt am besten?


    Schöne Grüße Christian
    Montag, 6. Februar 2012 12:51
  • Hallo Christian,

    da wäre das OutputDataReceived Ereignis besser geeignet,
    siehe auch die Antworten (und Anmerkugnen von Jon Skeet) zu:
    process.standardoutput.ReadToEnd() always empty?

    Wenn Du die Ausgabe aus dem separaten Thread in einer TextBox anzeigen willst,
    wäre dafür ein Control.Invoke fällig, siehe dazu:
    http://blog.rthand.com/post/2009/06/26/A-better-Invoke.aspx

    Gruß Elmar

     

    Montag, 6. Februar 2012 13:26
  • Hallo,

    so wie ich das jetzt heraus gelesen habe, gehört Invoke zu WindowsForms. Gibt es für WPF etwas vergleichbares, da ich jetzt einen Fehler bekomme, der besagt, dass das Objekt, welches ich Aufrufen möchte, zu einem anderen Thread gehört.


     


    Schöne Grüße Christian
    Montag, 6. Februar 2012 15:31
  • Hallo Christian,

    bei WPF wäre das Gegenstück der Dispatcher, siehe z. B.:
    Aus neuem Thread ein WPF Window beeinflussen

    Gruß Elmar

    Montag, 6. Februar 2012 17:32
  • Dankeschön für die Hilfe! Jetzt klappt es... :)
    Schöne Grüße Christian
    Montag, 6. Februar 2012 20:19