Seite 1 von 2 12 Letzte
  1. #1
    Avatar von AFU
    Registriert seit
    19.11.2011
    Beiträge
    359
    Thanked 75 Times in 61 Posts

    Standard C#: Batch Datei starten

    Hallo,

    Ich habe die Challenge, dass es ich es nicht zusammenbringe, eine Batch-Datei über die CMD.exe zu starten.


    Hier mal die Definition, um "Commands" auszuführen. Dies klappt bei grunsätzlich, außer zum Installieren von Batch-Files. Für alle unten angeführten Varianten erhalte ich meistens von der CMD die Rückmeldung: "The System cannot find the specified file", obwohl der "/c " Paraemter verwendet wird. toInstall beeinhaltet den Zielpfad zb: C:\installation. Die Batch-Datei findet sich dann unter C:\installation\test\install.bat.
    Gehe ich manuell ins Verzeichnis und führe die Batch-Datei aus, klappt es einwandrei.

    Code:
    public void ExecuteCommandSync(object command)
            {
                try
                {
                    // create the ProcessStartInfo using "cmd" as the program to be run,
                    // and "/c " as the parameters.
                    // Incidentally, /c tells cmd that we want it to execute the command that follows,
                    // and then exit.
                    System.Diagnostics.ProcessStartInfo procStartInfo =
                        new System.Diagnostics.ProcessStartInfo("cmd", "/c " + command);
    
                    // The following commands are needed to redirect the standard output.
                    // This means that it will be redirected to the Process.StandardOutput StreamReader.
                    procStartInfo.RedirectStandardOutput = true;
                    procStartInfo.UseShellExecute = false;
                    // Do not create the black window.
                    procStartInfo.CreateNoWindow = true;
                    // Now we create a process, assign its ProcessStartInfo and start it
                    System.Diagnostics.Process proc = new System.Diagnostics.Process();
                    proc.StartInfo = procStartInfo;
                    proc.Start();
                    //                proc.WaitForExit();
                    // Get the output into a string
                    string result = proc.StandardOutput.ReadToEnd();
                    // Display the command output.
                    Console.WriteLine(result);
                    textBox1.Text += result;
                }
                catch (Exception objException)
                {
                    // Log the exception
                }
            }

    Hier dann die Versuche, es über diese Funktion aufzurufen

    Code:
    string fulltest = toInstall + "\\server\\test\\install.bat
    string command = "start cmd.exe /c cd /d " + fulltest + " &&  install.bat";
    ExecuteCommandSync(command);

    Weitere Versuche unabhängig von der public void Methode oben.

    Code:
    Process P = new Process();
    P.StartInfo.FileName = "cmd.exe"; at";
    P.StartInfo.Arguments = @"/c " + fulltest;
    P.Start();
    Code:
    string strCmdText;
    strCmdText = "/C " + toInstall + "\\server\\test\\install.bat";
    System.Diagnostics.Process.Start("CMD.exe", strCmdText);
    Code:
    System.Diagnostics.Process.Start("cmd.exe", @"/c toInstall + '\\server\\test\\install.bat'");
    ProcessInfo = new ProcessStartInfo("cmd.exe", "/c " + toInstall + "\\server\\test\\install.bat");
    System.Diagnostics.Process.Start(toInstall + "\\server\\test\\install.bat");
    Ich brauche keine komplexe Methode/Funktion, ich möchte nur genau einmal die install.bat ausführen. Alternativ auch gerne über powershell. Auch das habe ich mit dem gleichen Ergebnis getestet.
    Geändert von AFU (21.03.2019 um 09:59 Uhr)

  2. #2
    Avatar von Nuebel
    Registriert seit
    23.11.2013
    Beiträge
    446
    Thanked 361 Times in 236 Posts

    Standard AW: C#: Batch Datei starten

    Code:
    string fulltest = toInstall + "\\server\\test\\install.bat
    [...]
    P.StartInfo.Arguments = @"/c " + fulltest;
    Bezieht sich das @-Token in C# hier nur auf das "/c" oder auf den konkatenierten String "/c " + fulltest? Wenn Letzteres der Fall ist, werden die doppelten Backlsashes (\\) in fulltest wörtlich interpretiert. Lass das @ mal weg. Bzw. lass dir mal den String command ausgeben. Windows-Pfadangaben sind scheiße.
    Geändert von Nuebel (21.03.2019 um 10:16 Uhr)

  3. The Following User Says Thank You to Nuebel For This Useful Post:

    DMW007 (21.03.2019)

  4. #3
    Avatar von AFU
    Registriert seit
    19.11.2011
    Beiträge
    359
    Thanked 75 Times in 61 Posts

    Standard AW: C#: Batch Datei starten

    habe ich geprüft, passt.

  5. #4
    Avatar von DMW007
    Registriert seit
    15.11.2011
    Beiträge
    6.081
    Thanked 9.118 Times in 2.995 Posts
    Blog Entries
    5

    Standard AW: C#: Batch Datei starten

    Im oberen Post steht etwas von lokalen C:\ Pfaden, die meisten Beispiele enthalten aber UNC-Pfade. Was davon hast du erfolglos getestet?

    using System;
    using System.Diagnostics;

    namespace BatchStartTest {
    class Program {
    static void Main(string[] args) {
    string fileName = @"/c C:\test.bat";
    var procStartInfo = new ProcessStartInfo("cmd", fileName) {
    RedirectStandardOutput = true,
    UseShellExecute = false
    };
    procStartInfo.RedirectStandardOutput = true;
    procStartInfo.UseShellExecute = false;

    var proc = new Process {
    StartInfo = procStartInfo
    };
    proc.Start();

    string result = proc.StandardOutput.ReadToEnd();
    Console.WriteLine(result);
    Console.Read();
    }
    }
    }

    Wobei du nicht mal eine explizite cmd.exe Instanz brauchst, wenn es nur ein Batch-Skript ist. Dann reicht auch einfach

    string fileName = @"C:\test.bat";
    var procStartInfo = new ProcessStartInfo(fileName) {
    RedirectStandardOutput = true,
    UseShellExecute = false
    };

    Gibt in beiden Fällen das aus, was C:\test.bat nach stdout schreibt. Wie die Backslashes escaped werden spielt keine Rolle, man könnte genau so gut händisch "C:\\test.bat" escapen.

    Wenn du eine gesonderte cmd Shell startest und darin Befehle ausführst wie bei dem Beispiel
    Zitat Zitat von AFU Beitrag anzeigen
    Code:
    // [...]
    string command = "start cmd.exe /c cd /d " + fulltest + " &&  install.bat";
    musst du deine Befehle quoten, sobald Leerzeichen verwendet werden. Die Shell kann nicht wissen, welche Argumente zu welcher Instanz gehören und interpretiert alles nach einem Leerzeichen als neues Argument bzw. eigenständigen Befehl:
    Code:
    C:\Users\Daniel>cmd /c cd C:\ && test.bat
    Der Befehl "test.bat" ist entweder falsch geschrieben oder
    konnte nicht gefunden werden.
    
    C:\Users\Daniel>cmd /c "cd C:\ && test.bat"
    
    C:\>echo "test.bat called"
    "test.bat called"
    Der Rote Teil wird an die neu erstellte cmd Instanz übergeben. Sie wechselt das Arbeitsverzeichnis nach C:\ und wird anschließend beendet, weil der grüne Teil in der aufrufenden Shell startet. Diese wiederum befindet sich im Profilordner und findet test.bat daher nicht. Im zweiten Beispiel werden beide Befehl dem /c Argument übergeben und dadurch miteinander verkettet ausgeführt, wie erwartet.

    Je nachdem was du da startest ist das vorherige Wechseln des Arbeitsverzeichnisses btw eine gute Idee. Wenn das was komplexeres ist, dass ggf. andere Dateien/Skripte ausführt und relative Pfade verwendet, werden die dann nicht zerschossen.


  6. The Following 2 Users Say Thank You to DMW007 For This Useful Post:

    AFU (22.03.2019), Nuebel (22.03.2019)

  7. #5
    Avatar von AFU
    Registriert seit
    19.11.2011
    Beiträge
    359
    Thanked 75 Times in 61 Posts

    Standard AW: C#: Batch Datei starten

    Hallo Daniel,

    danke fürs Feedback. Es sind nur lokale Pfade. Der Pfad wird aber aus Variable + String zusammengesetzt.
    Zb
    Code:
    string toinstall = "C:\installation":
    string path = toInstall + "\\test\\bla";
    Mir ist nicht ganz klar, wie ich den unentstehenden Part mit den "" für Variable + String anpassen soll:

    Code:
    string fileName = @"C:\test.bat";
    var procStartInfo = new ProcessStartInfo(fileName) {
        RedirectStandardOutput = true,
        UseShellExecute = false
    };
    Kannst du hier aushelfen?
    Geändert von AFU (23.03.2019 um 22:23 Uhr)

  8. #6
    Avatar von DMW007
    Registriert seit
    15.11.2011
    Beiträge
    6.081
    Thanked 9.118 Times in 2.995 Posts
    Blog Entries
    5

    Standard AW: C#: Batch Datei starten

    ProcessStartInfo erhält im Konstruktor den Pfad der auszuführenden Datei. Ob der Pfad nun hartkodiert in einer Variable steht oder dynamisch zusammengebaut wird, spielt am Ende keine Rolle.

    string installBasePath = "C:\\install-test";
    string fullScriptPath = $"{installBasePath}\\test.bat";
    var procStartInfo = new ProcessStartInfo(fullScriptPath) {
    RedirectStandardOutput = true,
    UseShellExecute = false
    };

    Wichtig ist, dass der Backslash entweder korrekt maskiert wird wie oben (\\ statt \) oder du den String wörtlich interpretieren lässt (vorangestelltes @):

    string installBasePath = @"C:\install-test";
    string fullScriptPath = $@"{installBasePath}\test.bat";

    OT: Bei solchen Themen würde ich mir auch mal Gedanken machen, ob es da keine besseren Wege für gibt. Je nachdem was deine Skripte machen, kann das ggf. auch eine native Bibliothek. Im besten Falle spart das nicht nur Arbeit, sondern auch Nerven und ist flexibler.


  9. The Following 2 Users Say Thank You to DMW007 For This Useful Post:

    AFU (23.03.2019), Darkfield (24.03.2019)

  10. #7
    Avatar von AFU
    Registriert seit
    19.11.2011
    Beiträge
    359
    Thanked 75 Times in 61 Posts

    Standard AW: C#: Batch Datei starten

    Leider klappt es noch nicht, irgendwas mache ich falsch:

    Meine Log-Methode gibt folgendes für die Variablen vor Ausführung der Install.bat retour:
    Code:
    Variable toInstall: C:\bla
    Varialbe FullscriptPath: C:\bla\server\blabla\install.bat
    Meiner Ansicht nach sieht meine toInstall-Variable so aus: C:\\bla
    Code:
     log("Variable toInstall: " + toInstall + "\r\n");
                    string fullScriptPath = $"{toInstall}\\server\\blabla\\install.bat";
                    log("Varialbe FullscriptPath: " + fullScriptPath + "\r\n");
                    var procStartInfo = new ProcessStartInfo(fullScriptPath)
                    {
                        RedirectStandardOutput = true,
                        UseShellExecute = false
                    };
                    var proc = new Process
                    {
                        StartInfo = procStartInfo
                    };
                    proc.Start();
    Ich vermute mal, dass noch irgendwas mit den Backslashes nicht passt.

  11. #8
    Avatar von DMW007
    Registriert seit
    15.11.2011
    Beiträge
    6.081
    Thanked 9.118 Times in 2.995 Posts
    Blog Entries
    5

    Standard AW: C#: Batch Datei starten

    Da das in meinem PoC oben funktioniert hat und dein Pfad syntaktisch korrekt aussieht, würde ich noch mal den Pfad prüfen. Kannst den ja einfach mal in die Suche kopieren und schauen ob er die Datei findet, oder ob sich ein Tippfehler eingeschlichen hat. Ansonsten schau mal in stdout was das Skript dorthin schreibt:

    string stdout = proc.StandardOutput.ReadToEnd();
    Console.WriteLine(stdout);




    Wenn das Skript etwas installiert und somit eine Weile laufen muss, wäre es sicher auch sinnvoll, proc.WaitForExit(); nach dem Start aufzurufen. Falls notwendig mit entsprechend hohem Timeout als Parameter.


  12. The Following User Says Thank You to DMW007 For This Useful Post:

    AFU (23.03.2019)

  13. #9
    Avatar von AFU
    Registriert seit
    19.11.2011
    Beiträge
    359
    Thanked 75 Times in 61 Posts

    Standard AW: C#: Batch Datei starten

    Stdout ist leer.
    Ich habe das Problem gefunden. Ich habe dazu die CMD in einem anderen Verzeichnis gestartet und probiert, den Pfad direkt aufzurufen, einmal mit mit einem bzw. zwei Slashes. Siehe Screenshot was dabei rauskommt.
    Auch das Ausführen beider Pfade mit Hochkomma klappt nicht.
    Ich muss quasi zuerst irgendwie ins Verzeichnis navigieren und dann ausführen, anders klappt es nicht.
    Hast du hier noch eine Idee?
    Geändert von AFU (23.03.2019 um 22:23 Uhr)

  14. #10
    Avatar von DMW007
    Registriert seit
    15.11.2011
    Beiträge
    6.081
    Thanked 9.118 Times in 2.995 Posts
    Blog Entries
    5

    Standard AW: C#: Batch Datei starten



    Dass selbst der maskierte Pfad funktioniert, wundert mich zugegeben auch etwas. Aber wie man sieht ist es kein generelles Problem der Shell oder des C# Codes sondern hängt damit zusammen, was dieses Skript macht. Daher auch die Nachfrage und Anregung, das versuchen nativ zu lösen.

    Wenn das Batchskript andere Dateien mit relativen Pfaden referenziert, findet er die ohne entsprechend gesetzten cwd nicht. Die Fehlermeldung wird vermutlich daher stammen. Das kannst du nur auf zwei Arten lösen:
    1. Das Batchskript ist entsprechend flexibel geschrieben und nutzt %~dp0 als Präfix für alle Befehle, um absolute Pfadangaben zum Skript selbst hin zu erzeugen
    2. Wie hier gezeigt das Arbeitsverzeichnis vorher durch cd entsprechend zu wechseln:
    Code:
    cmd /c "cd C:\install-test && test.bat"
    Beispiel:
    Code:
    :: test.bat
    @echo "Check ffmpeg version"
    ffmpeg -version
    Wird das aus einem anderen Verzeichnis aufgerufen, wirft der ffmpeg Aufruf einen Fehler, weil er relativ sucht (hier in C:\Users\Daniel):
    Code:
    C:\Users\Daniel>C:\install-test\test.bat
    "Check ffmpeg version"
    
    C:\Users\Daniel>ffmpeg -version
    Der Befehl "ffmpeg" ist entweder falsch geschrieben oder
    konnte nicht gefunden werden.
    
    C:\Users\Daniel>cmd /c "cd C:\install-test && test.bat"
    "Check ffmpeg version"
    
    C:\install-test>ffmpeg -version
    ffmpeg version N-93447-g5252d594a1 Copyright (c) 2000-2019 the FFmpeg developers
    built with gcc 8.2.1 (GCC) 20190212
    ...
    Wenn man den ffmpeg Aufruf nun mit absolutem Pfad durchführt
    Code:
    @set cwd=%~dp0
    %cwd%ffmpeg -version
    Dann kann das Skript auch aus einem anderen Arbeitsverzeichnis heraus aufgerufen werden:
    Code:
    C:\Users\Daniel>C:\install-test\ffmpeg -version
    ffmpeg version N-93447-g5252d594a1 Copyright (c) 2000-2019 the FFmpeg developers
    built with gcc 8.2.1 (GCC) 20190212
    ...


  15. The Following User Says Thank You to DMW007 For This Useful Post:

    AFU (23.03.2019)

Seite 1 von 2 12 Letzte

Ähnliche Themen

  1. Batch-Datei mit Administratorrechten starten
    Von DotNet im Forum Windows
    Antworten: 1
    Letzter Beitrag: 09.08.2016, 22:10
  2. Funktion mit Parameter in Batch-Script
    Von DotNet im Forum Shellprogrammierung
    Antworten: 2
    Letzter Beitrag: 26.03.2016, 23:10
  3. Batch mit Maus bedienen???
    Von Testgamer100 im Forum Andere
    Antworten: 3
    Letzter Beitrag: 04.02.2016, 20:42
  4. Windows 10 erkennt jar Datei als rar Datei
    Von Y zu dem K im Forum Windows
    Antworten: 5
    Letzter Beitrag: 02.10.2015, 19:10
  5. (.bat) Batch Tutorial
    Von MC Phlegmatisch im Forum Tutorials
    Antworten: 0
    Letzter Beitrag: 31.03.2012, 13:35
Diese Seite nutzt Cookies, um das Nutzererlebnis zu verbessern. Klicken Sie hier, um das Cookie-Tracking zu deaktivieren.