none
Command Shell steuern RRS feed

  • Frage

  • Hallo,

    ich habe eine Komandozeienprogramm ähnlich der cmd.exe die ich über C# Steuern möchte (mehrere Anweisungen hintereinander und eine Rückgabe (als String) damit ich entsprechend im Programm weiter verfahren kann)

    Danke für eure hilfe

    Montag, 1. Oktober 2012 08:15

Antworten

  • Hallo,

    Sieh dir bitte die Dokumentation und die Beispiele zur Klasse Process und zur Process.Start-Methode an. Um eine Rückgabe zu erhalten, mußt Du über ProcessStartInfo.RedirectStandardOutput den Ausgabestrom umleiten.

    Mir ist nicht ganz klar, was Du mit "mehrere Anweisungen hintereinander" meinst. Wenn Du damit direkte Eingaben meinst, die das Program erwartet, dann mußt Du über process.StandardInput.WriteLine(...) die entspr. Eingaben tätigen.

    Siehe auch:
    Manish Ranjan Kumar - How to redirect StandardInput/Output of an application

    Gruß
    Marcel

    Montag, 1. Oktober 2012 09:18
    Moderator
  • Hallo Klartext90,

    Das kann nicht dein gesamter Code sein. Dein Prozess würde sich damit alsbald wieder verabschieden (womöglich ohne eine einzige Zeile auszugeben). Ich vermute aber, dass da später im Code irgendwo noch ein p.WaitForExit() oder eine Warteschleife folgt. Zum anderen, solltest Du's mal mit asynchronen Lesevorgängen versuchen, da es durchaus sein kann, dass es eine Weile dauert bis die Ausgabe erfolgt. Hier ein kleines Beispiel:

    using System;
    using System.Diagnostics;
    namespace ConsoleApplication10
    {
        class Program
        {
            static void Main(string[] args)
            {
                try
                {
                    using (Process p = new Process())
                    {
                        p.StartInfo.UseShellExecute = false;
                        p.StartInfo.RedirectStandardError = true;
                        p.StartInfo.RedirectStandardOutput = true;
                        p.StartInfo.RedirectStandardInput = true;
                        p.StartInfo.CreateNoWindow = false;
                        p.StartInfo.FileName = "sqlcmd.exe";
                        p.StartInfo.Arguments = "-d Northwind";
                        p.OutputDataReceived += p_OutputDataReceived;
                        p.ErrorDataReceived += p_ErrorDataReceived;
                        p.Start();
                        p.BeginErrorReadLine();
                        p.BeginOutputReadLine();
                        p.StandardInput.WriteLine("SELECT TOP(10) CustomerID FROM Customers");
                        p.StandardInput.WriteLine("GO");
                        p.WaitForExit();
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }
                Console.WriteLine("\n\nZum Beenden Taste drücken.");
                Console.ReadKey(true);
            }
            static void p_ErrorDataReceived(object sender, DataReceivedEventArgs e)
            {
                Console.WriteLine("ERROR: {0}", e.Data);
            }
            static void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
            {
                Console.WriteLine("Output: {0}", e.Data);
            }
        }
    }

    (Was im obigen Beispiel vielleicht wie ein Deadlock aussieht ist in Wirklichkeit nur ein Warten von sqlcmd.exe auf Benutzereingabe.)

    Außerdem: Es gibt Programme die gar nicht in den StandardOutput schreiben. Dann mußt Du dich wohl oder übel mit dem ExitCode zufriedengeben.

    Gruß
    Marcel

    Dienstag, 2. Oktober 2012 13:35
    Moderator

Alle Antworten

  • Da deine Fragestellung so allgemein ist, hier mal ein hilfreicher Link zum grundsätzlichen Entwickeln eines Konsolenprogramms / Cmd-Applikation:

    http://msdn.microsoft.com/de-de/library/0wc2kk78%28v=vs.90%29.aspx


    Cheers, dnlg

    Montag, 1. Oktober 2012 08:53
  • Hallo,

    Sieh dir bitte die Dokumentation und die Beispiele zur Klasse Process und zur Process.Start-Methode an. Um eine Rückgabe zu erhalten, mußt Du über ProcessStartInfo.RedirectStandardOutput den Ausgabestrom umleiten.

    Mir ist nicht ganz klar, was Du mit "mehrere Anweisungen hintereinander" meinst. Wenn Du damit direkte Eingaben meinst, die das Program erwartet, dann mußt Du über process.StandardInput.WriteLine(...) die entspr. Eingaben tätigen.

    Siehe auch:
    Manish Ranjan Kumar - How to redirect StandardInput/Output of an application

    Gruß
    Marcel

    Montag, 1. Oktober 2012 09:18
    Moderator
  • Danke bin jezt schon ein gutes Stück weiter, nur habe ich jezt noch Probleme mit dem Output

    ich möchte die Ausgabe nach dem StandardInput auslesen komme aber egal wie ich es drehe und wende immer wieder zu einer Deadlockbedingung, wie kann ich das umgehen?

                Process p = new Process();
                p.StartInfo.UseShellExecute = false;
                p.StartInfo.RedirectStandardOutput = true;
                p.StartInfo.RedirectStandardInput = true;
                p.StartInfo.CreateNoWindow = true;
                p.StartInfo.FileName = "TNCcmd.exe";
                p.StartInfo.Arguments = @"-Ilocalhost";
                p.Start();
                p.StandardInput.WriteLine("ACCSESS P ");
                string output = p.StandardOutput.ReadToEnd();




    • Bearbeitet Klartext90 Montag, 1. Oktober 2012 11:02
    Montag, 1. Oktober 2012 11:00
  • Hallo Klartext90,

    Das kann nicht dein gesamter Code sein. Dein Prozess würde sich damit alsbald wieder verabschieden (womöglich ohne eine einzige Zeile auszugeben). Ich vermute aber, dass da später im Code irgendwo noch ein p.WaitForExit() oder eine Warteschleife folgt. Zum anderen, solltest Du's mal mit asynchronen Lesevorgängen versuchen, da es durchaus sein kann, dass es eine Weile dauert bis die Ausgabe erfolgt. Hier ein kleines Beispiel:

    using System;
    using System.Diagnostics;
    namespace ConsoleApplication10
    {
        class Program
        {
            static void Main(string[] args)
            {
                try
                {
                    using (Process p = new Process())
                    {
                        p.StartInfo.UseShellExecute = false;
                        p.StartInfo.RedirectStandardError = true;
                        p.StartInfo.RedirectStandardOutput = true;
                        p.StartInfo.RedirectStandardInput = true;
                        p.StartInfo.CreateNoWindow = false;
                        p.StartInfo.FileName = "sqlcmd.exe";
                        p.StartInfo.Arguments = "-d Northwind";
                        p.OutputDataReceived += p_OutputDataReceived;
                        p.ErrorDataReceived += p_ErrorDataReceived;
                        p.Start();
                        p.BeginErrorReadLine();
                        p.BeginOutputReadLine();
                        p.StandardInput.WriteLine("SELECT TOP(10) CustomerID FROM Customers");
                        p.StandardInput.WriteLine("GO");
                        p.WaitForExit();
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }
                Console.WriteLine("\n\nZum Beenden Taste drücken.");
                Console.ReadKey(true);
            }
            static void p_ErrorDataReceived(object sender, DataReceivedEventArgs e)
            {
                Console.WriteLine("ERROR: {0}", e.Data);
            }
            static void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
            {
                Console.WriteLine("Output: {0}", e.Data);
            }
        }
    }

    (Was im obigen Beispiel vielleicht wie ein Deadlock aussieht ist in Wirklichkeit nur ein Warten von sqlcmd.exe auf Benutzereingabe.)

    Außerdem: Es gibt Programme die gar nicht in den StandardOutput schreiben. Dann mußt Du dich wohl oder übel mit dem ExitCode zufriedengeben.

    Gruß
    Marcel

    Dienstag, 2. Oktober 2012 13:35
    Moderator
  • Hallo Klartext90,

    Ich gehe davon aus, dass die Antwort Dir weitergeholfen hat.
    Solltest Du noch "Rückfragen" dazu haben, so gib uns bitte Bescheid.

    Grüße,
    Robert


    Robert Breitenhofer, MICROSOFT   Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip Entwickler helfen Entwickler“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.

    Dienstag, 23. Oktober 2012 11:21
    Moderator