1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

c# Auf cmd zugreifen

Discussion in 'Tipps & Tricks' started by Cre3per, Dec 30, 2012.

  1. Cre3per

    Cre3per Member

    Joined:
    Oct 22, 2012
    Messages:
    764
    Likes Received:
    2
    Ich kann einige Befehle ausführen, jedoch keine, die aufgelistet werden, wenn ich "help" eingebe. Wass muss ich ändern bzw. hinzufügen, damit ich alles benutzen kann, was ich normalerweise auch in der Eingabeaufforderung benutzen kann?
    Code:
    using System;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Diagnostics;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                try
                {
                    Process Test = new Process();
                    Test.StartInfo.FileName = textBox1.Text;
                    Test.StartInfo.UseShellExecute = false;
                    Test.StartInfo.Arguments = textBox2.Text;
                    Test.StartInfo.RedirectStandardOutput = true;
                    Test.Start();
                    richTextBox1.Text = Test.StandardOutput.ReadToEnd();
    
                }
                catch (Exception error)
                {
                    MessageBox.Show(error.Message);
                }
            }
        }
    }
    
    
     
  2. krusty

    krusty New Member

    Joined:
    Sep 8, 2012
    Messages:
    182
    Likes Received:
    0
    Code:
    richTextBox1.Text = Test.StandardOutput.ReadToEnd();
    diese Zeile ließt EINMAL den Output der Konsole.

    Du musst in einer Schleife durchgehend aus dem Outputstream lesen.
    Das wird problematisch, weil diese Schleife zwangsläufig die Form blockieren wird. Das bedeutet du solltest mit Threads arbeiten.
     
  3. Cre3per

    Cre3per Member

    Joined:
    Oct 22, 2012
    Messages:
    764
    Likes Received:
    2
    Warum?
     
  4. krusty

    krusty New Member

    Joined:
    Sep 8, 2012
    Messages:
    182
    Likes Received:
    0
    also, du solltest versuchen zu verstehen, was du da gemacht hast.

    1. du startest einen Prozess
    2. der gestartete Prozess hat einen
    Code:
    StandardOutput 
    und einen
    Code:
    StandardInput
    , damit kann man mit dem gestarteten Prozess sprechen, also ihm Texte schicken und Texte empfangen.
    In der Regel benutzt man dafür einen StreamWriter und StreamReader.

    Was du momentan machst, ist sehr unschön:
    immer wenn der Button gedrückt wird, startest du einen neuen Prozess.
    Besser wäre es, wenn du einmal die cmd startest und dann immer mit dem einzelnen Prozess arbeitest.

    wie gesagt,
    starte eine Funktion im Thread, in der in einerschleife dauerhaft der StandardOutput ausgelesen wird und das Ergebnis in deine Textbox gepackt wird.
     
  5. Cre3per

    Cre3per Member

    Joined:
    Oct 22, 2012
    Messages:
    764
    Likes Received:
    2
    Ich habe es versucht aber ich glaube nicht, dass ich dich verstanden habe. Wenn ich jetzt den Button klicke wird mein befehl kurz ausgeführt/angezeigt und dann stürzt das programm ab.

    Code:
    using System;
    using System.Windows.Forms;
    using System.Diagnostics;
    using System.Drawing;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Linq;
    using System.Text;
    using System.Threading;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            Process Test = new Process();
            public Form1()
            {
                InitializeComponent();
            }
            void Message()
            {
                for (int i = 1; i < 2; )
                {
                    richTextBox1.Text = Test.StandardOutput.ReadToEnd();
                    Thread.Sleep(500);
                }
            }
            private void button1_Click(object sender, EventArgs e)
            {
                try
                {
                    Test.StartInfo.UseShellExecute = false;
                    Test.StartInfo.RedirectStandardOutput = true;
                    Test.StartInfo.Arguments = textBox2.Text;
                    Test.StartInfo.FileName = textBox1.Text;
                    Test.Start();
                    Message();
                    //Process Test = new Process();
                    //Test.StartInfo.FileName = textBox1.Text;
                    //Test.StartInfo.UseShellExecute = false;
                    //Test.StartInfo.Arguments = textBox2.Text;
                    //Test.StartInfo.RedirectStandardOutput = true;
                    //Test.Start();
                    //richTextBox1.Text = Test.StandardOutput.ReadToEnd();
                }
                catch (Exception error)
                {
                    MessageBox.Show(error.Message);
                }
    
    
            }
    
    
            
        }
    }
    
    
     
  6. krusty

    krusty New Member

    Joined:
    Sep 8, 2012
    Messages:
    182
    Likes Received:
    0
    Du solltest auf eine while schleife zurückgreifen.
    das ganze sollte jetzt noch in einen thread, damit die Form nicht blockiert wird.
    Poste bitte die Fehlermeldung, sonst kann ich damit nichts anfangen.
     
  7. Cre3per

    Cre3per Member

    Joined:
    Oct 22, 2012
    Messages:
    764
    Likes Received:
    2
    Fehlermeldung gibts nicht, das progromm reagiert einfach nicht mehr auf irgendetwas.
    Was meinst du mit "in einen Thread"?
     
  8. hoschi111

    hoschi111 Administrator Staff Member Administrator

    Joined:
    Dec 19, 2017
    Messages:
    1,445
    Likes Received:
    0
    In VB.Net gibt es fürs Threading den Backgroundworker. Dem kann man dann Aufgaben geben, die im Hintergrund abgearbeitet werden, ohne die Form zu blocken.
     
  9. krusty

    krusty New Member

    Joined:
    Sep 8, 2012
    Messages:
    182
    Likes Received:
    0
    Na also, das Programm stürzt nicht ab, sondern es blockiert.
    Threading bedeutet, dass ein Programm "gleichzeit" sachen ausführen kann.

    Das Problem ist das folgende:
    1. dein Programm muss die Form aktualisieren, das passiert im MainThread.
    2. dein Programm wartet auf eine Nachricht der Shell auch im MainThread.

    Die 2. blockiert die 1.
    Deshalb solltest du Message Methode in einen Thread schmeißen, damit wird der Mainthread nicht mehr blockiert.

    Das nennt man Multithreading, solltest du dir mal was zu durchlesen, macht die Programme um einiges effizienter.
     
  10. Cre3per

    Cre3per Member

    Joined:
    Oct 22, 2012
    Messages:
    764
    Likes Received:
    2
    Ich habe jetzt einen Backgroundworker hinzugefügt. CMD öffnet sich kurz, schließt sich aber sofort wieder. Programm blockiert nicht und stürzt nicht ab.

    Code:
    using System;
    using System.Windows.Forms;
    using System.Diagnostics;
    using System.Drawing;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Linq;
    using System.Text;
    using System.Threading;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            Process Test = new Process();
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                try
                {
                    Test.StartInfo.UseShellExecute = false;
                    Test.StartInfo.RedirectStandardOutput = true;
                    Test.StartInfo.Arguments = textBox2.Text;
                    Test.StartInfo.FileName = textBox1.Text;
                    Test.Start();
                    //Process Test = new Process();
                    //Test.StartInfo.FileName = textBox1.Text;
                    //Test.StartInfo.UseShellExecute = false;
                    //Test.StartInfo.Arguments = textBox2.Text;
                    //Test.StartInfo.RedirectStandardOutput = true;
                    //Test.Start();
                    //richTextBox1.Text = Test.StandardOutput.ReadToEnd();
                }
                catch (Exception error)
                {
                    MessageBox.Show(error.Message);
                }
    
    
            }
    
            private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
            {
                while (1 < 2)
                {
                    richTextBox1.Text = Test.StandardOutput.ReadToEnd();
                }
            }
    
        }
    }
    
     
  11. krusty

    krusty New Member

    Joined:
    Sep 8, 2012
    Messages:
    182
    Likes Received:
    0
    lol, du musst den backgorundworker auch starten oO
    sorry, aber du solltest wirklich, unbedingt die grundlagen der sprachen lernen, in denen du arbeitest.

    edit: benutze bitte while(true)
     
  12. Cre3per

    Cre3per Member

    Joined:
    Oct 22, 2012
    Messages:
    764
    Likes Received:
    2
    Ich warte als auf ne antwort und bemerke erst jetzt, dass mein Beutrag nicht gepostet wurde.
    Also. Ich weis, dass man den aktivieren muss, habe aber nicht herrausgefunden wie.
     
  13. Cre3per

    Cre3per Member

    Joined:
    Oct 22, 2012
    Messages:
    764
    Likes Received:
    2
    Code:
    using System;
    using System.Windows.Forms;
    using System.Diagnostics;
    using System.Drawing;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Linq;
    using System.Text;
    using System.Threading;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            Process Test = new Process();
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                try
                {
                    Test.StartInfo.UseShellExecute = false;
                    Test.StartInfo.RedirectStandardOutput = true;
                    Test.StartInfo.Arguments = textBox2.Text;
                    Test.StartInfo.FileName = textBox1.Text;
                    Test.Start();
                    backgroundWorker1.RunWorkerAsync();
                    //Process Test = new Process();
                    //Test.StartInfo.FileName = textBox1.Text;
                    //Test.StartInfo.UseShellExecute = false;
                    //Test.StartInfo.Arguments = textBox2.Text;
                    //Test.StartInfo.RedirectStandardOutput = true;
                    //Test.Start();
                    //richTextBox1.Text = Test.StandardOutput.ReadToEnd();
                }
                catch (Exception error)
                {
                    MessageBox.Show(error.Message);
                }
    
    
            }
    
            private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
            {
                while (true)
                {
                    richTextBox1.Text = Test.StandardOutput.ReadToEnd();
                }
            }
    
        }
    }
    
    Bei
    Code:
    richTextBox1.Text = Test.StandardOutput.ReadToEnd();
    bekomme ich den Fehler: "Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement richTextBox1 erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde."
     
  14. krusty

    krusty New Member

    Joined:
    Sep 8, 2012
    Messages:
    182
    Likes Received:
    0
    Control.checkforillegalcrosstheadcalls = false
    glaub ich.
     
  15. Cre3per

    Cre3per Member

    Joined:
    Oct 22, 2012
    Messages:
    764
    Likes Received:
    2
    Code:
            private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
            {
                while (true)
                {
                    Control.CheckForIllegalCrossThreadCalls = false;
                    richTextBox1.Text = Test.StandardOutput.ReadToEnd();
                    Thread.Sleep(1000);
                }
            }
    
    So stürzt es nicht mehr ab, in der Richtextbox steht aber nur solange etwas, bis Sleep abgelaufen ist
     
  16. hoschi111

    hoschi111 Administrator Staff Member Administrator

    Joined:
    Dec 19, 2017
    Messages:
    1,445
    Likes Received:
    0
    Weils schlecht programmiert ist ;)
    Code:
    Control.CheckForIllegalCrossThreadCalls = false;
    Das packst du nicht in while-schleife, form_load reicht.

    Und setze Sleep noch oben.
     
  17. krusty

    krusty New Member

    Joined:
    Sep 8, 2012
    Messages:
    182
    Likes Received:
    0
    Wie gesagt, eig benutzt man streamreader und streamwriter dafur.
    Wenn der prozess nichts mehr sendet, gibt readtoend nen leeren string zurueck.
    Du musst unbedingt grundlagen lernen !
     
  18. hoschi111

    hoschi111 Administrator Staff Member Administrator

    Joined:
    Dec 19, 2017
    Messages:
    1,445
    Likes Received:
    0
    Um dieser "Programmierung" treu zu bleiben, kann man doch
    string.IsNullOrEmpty benutzen, oder?