C# Zuerst .bat öffnen dann .exe prüfen

schlumpf1404

Cadet 1st Year
Registriert
Nov. 2010
Beiträge
8
Hallo Leute,

mein Problem ist folgendes:
Ich habe eine .bat mit der Parameter für ein Programm (.exe) festgelegt werden. Das heißt zuerst wird die .bat gestartet und diese öffnet mit den Parametern die .exe.

Ich möchte nun die .bat starten und die . exe überwachen, so dass wenn die .exe abschmiert ich die .bat einfach wieder starte und das in einer unendlich Schleife.

Ich danke euch schon im voraus!

Code:
namespace ConsoleApplication3
{
    class Program
    {
        static void Main(string[] args)
            
        {
            
        nochmal:
            System.Diagnostics.Process process = new System.Diagnostics.Process();
            System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
            startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
            //Bat
            Process P = new Process();
            P.StartInfo.FileName = "C:\\Users\\...\\start.bat";
            P.Start();
            System.Threading.Thread.Sleep(6000);
            System.Console.WriteLine("Der Server wurde erfolgreich gestartet.");
            //Server
            Process P1 = new Process();
            P1.StartInfo.FileName = "C:\\Users\\...\\server.exe";
            P1.WaitForExit();
            System.Console.WriteLine("Der  Server ist abgestürzt und wird in 10 Sekunden neu gestartet.");
            System.Console.WriteLine("....");
            System.Threading.Thread.Sleep(10000);
            goto nochmal;
        
        }
    }
}

Schlumpf-'
 
Warum startest du nicht gleich die EXE mit Parametern?
Dann kannst du sie auch gleich überwachen.
Das was ne BAT an Parametern ermitteln kann müsste doch direkt in C# auch gehen, oder nicht?

Falls nicht, kannst du nicht über das Erstellen eines neuen Prozess-Objekts an eine laufende EXE rankommen. Du musst den entsprechenden Prozess über die Liste der laufenden Prozesse raussuchen.
Das geht alles über die Process-Klasse.
 
Zuletzt bearbeitet:
Stimmt! Nur übernimmt er die Parameter nicht.

Code:
{
        nochmal:
            System.Diagnostics.Process process = new System.Diagnostics.Process();
            System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
            System.Diagnostics.Process.Start("C:\\Users\\...\\server.exe", "-batchmode -maxplayers 50... -nographics");
            startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
            Process P = new Process();
            P.StartInfo.FileName = "C:\\Users\\...\\server.exe";
            P.Start();
            System.Threading.Thread.Sleep(6000);
            System.Console.WriteLine("Der Server wurde erfolgreich gestartet.");
            P.WaitForExit();
            System.Console.WriteLine("Der Server ist abgestürzt und wird in 10 Sekunden neu gestartet.");
            System.Console.WriteLine("....");
            System.Threading.Thread.Sleep(10000);
            goto nochmal;
        
        }

Schlumpf-'
 
Du startest in Zeile 5 den Prozess mit Parametern und in Zele 9 nochmal ohne Parameter.

Müsste eigentlich so aussehen:
Code:
            Process p = new Process();
            p.StartInfo = new ProcessStartInfo("server.exe", "paramter1 paramter3 paramter3");
            p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            p.Start();

Danach kannst du mit p.WaitForExit warten bis der Prozess beendet ist und ihn dann nochmal starten.
 
Vielen Dank!
Es hat so funktioniert!
Code:
      {
        nochmal:
            System.Diagnostics.Process process = new System.Diagnostics.Process();
            System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
            startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;

            Process P = new Process();
            P.StartInfo = new ProcessStartInfo("C:\\Users\\...\\server.exe", "-Parameter1 -Parameter2 -Parameter3");
            P.Start();
            System.Threading.Thread.Sleep(6000);
            System.Console.WriteLine("Der Server wurde erfolgreich gestartet.");
            P.WaitForExit();
            System.Console.WriteLine("Der Server ist abgestürzt und wird in 10 Sekunden neu gestartet.");
            System.Console.WriteLine("....");
            System.Threading.Thread.Sleep(10000);
            goto nochmal;
        
        }
 
Könntest du noch das Label "nochmal" und das goto durch eine while(1) Schleife ersetzen, damit niemand einen Herzinfarkt erleidet ;)?
 
@schlumpf1404: Wenn du jetzt noch die überflüssigen Zeilen 3,4 und 5 löschst ist alles prima ;-). Und das was Boron sagt würd ich auch so unterschreiben. Goto gibts zwar als Befehl, aber man sollte sich nicht angewöhnen ihn zu benutzen weil größere Codeteile sonst sehr schnell unübersichtlich und fehleranfällig werden.
 
Danke für die zahlreiche Hilfe!
Ich hoffe so geht es einigermaßen? :)
Eine weitere Frage befindet sich unten.

Code:
    class Program
    {
        static void Main(string[] args)
        {
            for (; ; )
            {
                Process P = new Process();
                P.StartInfo = new ProcessStartInfo("C:\\Users\\...\\server.exe", "Parameter1, Parameter2");
                P.Start();
                System.Threading.Thread.Sleep(10000);
                Console.BackgroundColor = ConsoleColor.Green;
                Console.ForegroundColor = ConsoleColor.White;
                Console.WriteLine("Der Server wurde erfolgreich gestartet.");
                P.WaitForExit();
                Console.BackgroundColor = ConsoleColor.Red;
                Console.ForegroundColor = ConsoleColor.White;
                Console.WriteLine("Der Server ist abgestürzt und wird in 5 Sekunden neu gestartet.");
                Console.WriteLine("....");
                System.Threading.Thread.Sleep(5000);
            }
        }
    }
}

Und zwar überwacht dieses Programm ja einen Prozess und startet Ihn neu wenn er abstürtzt.
Ich möchte, dass sobald eine Bestimmte Fehlermeldung in der Console ausgegeben wird (welche das programm nur zum pausieren und nicht zum abstürzen bringt) das Programm geschlossen und neu gestartet wird.

Somit wenn Fehlercode "Error 114" auftauscht soll das Programm das bemerken und den Prozess / Server neu starten.
Ich danke das muss ich mit einer separaten .txt realisieren, welche alle ausgaben aus der Console abspeichert und analysiert? Wenn ja weiß ich nicht ganz wie ich das umsetzten soll.
 
Zuletzt bearbeitet:
Ich verstehe es richtig, dass server.exe eine Konsolenanwendung ist, die Ausgaben erzeugt aufgrund derer du den Prozess abschießen und neu starten willst?

Das Abgreifen der Konsolenausgabe der server.exe ist mit P.StandardOutput möglich. Das ist ein Stream-Objekt aus dem man mit der StreamReader-Klasse bequem lesen kann.

Das Abschießen funktioniert über P.Kill();

In dieser Konstellation kannst du aber nicht mit WaitForExit arbeiten, weil das ja den Programmablauf blockiert.
Du solltest das Exited-Event der Process-Klasse verwenden. Es benachrichtigt dich wenn der Prozess beendet wurde und du kannst reagieren (5 Sekunden warten und neu starten).
 
Hallo,
ich habe mich nun ein wenig mit StandardOutput bzw. StandardError befasst, um zu verstehen wie es funktioniert.

Meine Console die ich überwache gibt keine Standard Fehlermeldung mit z.B. "Error" aus sondern "Unresponsive for X seconds" X= Sekunden für die der Server nicht erreichbar ist.
Soweit ich es verstanden habe, sucht StandardError nach Standard Errors und wirft diese dann aus.

Ich möchte aber, dass die Funktion den Text "Unresponsive for X seconds" ("Unresponsive for" würde schon reichen) erkennt und dann eine folge von Befehlen ausführt, wie in diesem Fall das Neustarten des Programms / Servers.

Leider habe ich kein Beispiel gefunden, welches explizit auf Text oder Wortstücke in der Console eingeht und im Folgenden darauf reagiert und Befehle ausführt.

Schlumpf-'
 
Zurück
Oben