Eingabe / Ausgabe / Fehlerausgabe einer Konsole lesen / schreiben



  • Speziell geht es mir um die Eingabeaufforderung, die einige Sachen vertragen könnte wie sie zb. die Konsolen aus Kde / Gnome mitbringen. Ich habe mir dazu schon einiges an Freeware angeschaut, allerdings würde ich selbst gerne einige Anpassungen vornehmen.

    Auf den ersten Blick scheint es einem die Process Klasse des .NET Frameworks recht einfach zu machen. Man startet den Prozess "cmd.exe" und liest / schreibt in den entsprechenden Ereignissen aus / in die passenden Streams.

    Folgendes Problem ist dabei aufgetreten:

    Starte ich den Prozess mit Process.StartInfo.UseShellExecute = true; können die Streams nicht umgeleitet werden. Das Eingabeaufforderungprozess bleibt dabei solange bestehen, bis er manuell (durch schließen des Fensters oder Auffrufen von ***Process.Kill()***) beendet wird. Starte ich den Prozess dagegegen mit Process.StartInfo.UseShellExecute = false; bekomme ich zumindest keine Exception, dass Redirection nicht möglich ist. Allerdings wird des das Process.OutputDataReceived Event trotzdem nicht für die Standardmeldung

    Microsoft Windows XP [Version 5.1.2600]
    (C) Copyright 1985-2001 Microsoft Corp.

    C:\Dokumente und Einstellungen\Benutzer>

    ausgelöst und gleich nach Ausgabe dieser Meldung beendet sich der Eingabeaufforderungsprozess.

    Kann mir jemand sagen, wie ich die Sache richtig angehe?



  • Servus,

    das ist ein bissle knifflig mit der "cmd.exe". Ich hatte mich mal aus purer Langeweile etwas experimentell damit beschäftigt. Ich poste dir einfach mal meine ersten Ideen:

    using System;
    using System.Diagnostics;
    using System.IO;
    using System.Threading;
    
    namespace SmallCommand
    {
    	public sealed class CommandControl
    	{
            #region Fields
            public static event EventHandler ReceivedByte;
    
            private const int BufferSize = 102400;
            private static Process commandShell;
            private static Thread readThread;
            #endregion // Fields
    
            #region Constructor
    		static CommandControl()
    		{
    		}
            #endregion // Constructor
    
            #region Methods
            public static bool StartShell()
            {
                ProcessStartInfo startInfo       = new ProcessStartInfo("cmd.exe");
                //startInfo.Arguments = "/K C:";
                startInfo.RedirectStandardError  = true;
                startInfo.RedirectStandardOutput = true;
                startInfo.RedirectStandardInput  = true;
                startInfo.UseShellExecute        = false;
                startInfo.CreateNoWindow         = true;
    
                commandShell = Process.Start(startInfo);
    
                if ( commandShell == null )
                    return false;
    
                readThread = new Thread( new ThreadStart(ReadUntilEnd) );
                readThread.Start();
    
                return true;
            }
    
            public static void StopShell()
            {
                commandShell.Close();
            }
    
            private static void ReadUntilEnd()
            {
                int count = 0;
                int b = 0;
                int nullCount = 0;
                byte[] buffer = new byte[BufferSize];
                byte[] blindBuffer = null;
    
                while ( (b = commandShell.StandardOutput.BaseStream.Read(buffer, 0, buffer.Length)) > -1 )
                {
                    blindBuffer = new byte[b];
    
                    Buffer.BlockCopy(buffer, count, blindBuffer, 0, b);
                    if ( ReceivedByte != null )
                        ReceivedByte(null, new DataEventArgs(blindBuffer));
    
                    foreach ( byte nullItem in blindBuffer )
                    {
                        if ( nullItem == 0x0 )
                            nullCount++;
                    }
    
                    count += (b + nullCount);
    
                    nullCount = 0;
                }
            }
    
            public static void WriteCommand(string cmd)
            {
                commandShell.StandardInput.WriteLine(cmd);
            }
    
            #endregion // Methods
    	}
    }
    

    Vielleicht kannst du ja damit was anfangen....

    - StartShell führt einen Thread aus, der bis ins Nirvana den OutputStream liest
    - StopShell killt das ganze
    - WriteCommand sendet einen Text an die Kommandozeile

    Wirst es ja selbst sehen....

    HF
    Hellsgore


Anmelden zum Antworten