using System.Configuration; using System.Configuration.Internal; using System.Diagnostics; //using Microsoft.Extensions.Configuration; namespace PrometheusServiceManager; using System.ServiceProcess; // versions // V1 main release to customers system // V1.1 adding the Administrator option at the start // cancelled as the program would crash , to be investigated // V1.2 displaying starting complete 2025/10/15 // V1.3 detect stuck processes and kill them static class Program { private static readonly Dictionary ServicesList = ConfigurationManager.AppSettings.AllKeys.ToDictionary(key => key, key => ConfigurationManager.AppSettings[key]); public static bool KeycloakHidden = true; public static bool PostgreSqlHidden = true; public static readonly string version = "V1.3"; [STAThread] private static void StartService(string serviceName, int timeoutMilliseconds) { ServiceController service = new ServiceController(serviceName); try { TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds); service.Start(); service.WaitForStatus(ServiceControllerStatus.Running, timeout); } catch { // ... } } private static void StopService(string serviceName, int timeoutMilliseconds) { ServiceController service = new ServiceController(serviceName); try { TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds); service.Stop(); service.WaitForStatus(ServiceControllerStatus.Stopped, timeout); } catch { // ... } } public static void StartServices() { if(!Form1.KeycloakCheckBox.Checked) { Console.WriteLine("Keycloak unchecked"); ServicesList.Remove("_keycloak"); Form1.KeycloakCheckBox.Visible = false; } foreach (KeyValuePair Service in ServicesList) { //Console.WriteLine("checked: "+Form1.KeycloakCheckBox.Checked); //write the service name in the log Console.WriteLine("Starting: "+Service.Key); //start the service StartService(Service.Key, 1000); //update the text box Form1.TextDisplay.Text = "Starting: "+Service.Key; Form1.TextDisplay.Update(); //wait 1 second before Thread.Sleep(TimeSpan.FromSeconds(1)); //displaying end of operation Form1.TextDisplay.Text = "Starting complete ! "; Form1.TextDisplay.Update(); } } public static void ShutdownServices(bool keycloakRestartRequired) { //DisplayNetstat(); Thread.Sleep(TimeSpan.FromSeconds(3)); if(!Form1.KeycloakCheckBox.Checked) { Console.WriteLine("Keycloak unchecked"); ServicesList.Remove("_keycloak"); Form1.KeycloakCheckBox.Visible = false; } foreach (KeyValuePair Service in ServicesList.Reverse()) { //write the service name in the log Console.WriteLine("Stopping: "+Service.Key); //start the service StopService(Service.Key, 1000); //update the text box Form1.TextDisplay.Text = "Stopping: "+Service.Key; Form1.TextDisplay.Update(); //wait 1 second before Thread.Sleep(TimeSpan.FromSeconds(1)); //check if there is a process still active Process[] localByName = Process.GetProcessesByName(Service.Value); if (localByName.Length > 0) { Form1.TextDisplay.Text = "there is a process running "; Form1.TextDisplay.Update(); Thread.Sleep(TimeSpan.FromSeconds(1)); //loop through every process if multiples foreach (Process process in localByName) { process.Kill(); } Form1.TextDisplay.Text = "kill done "; Form1.TextDisplay.Update(); } //displaying end of operation Form1.TextDisplay.Text = "Stopping complete ! "; Form1.TextDisplay.Update(); } } public static void RestartServices(bool keycloakRestartRequired) { if(!Form1.KeycloakCheckBox.Checked) { Console.WriteLine("Keycloak unchecked"); ServicesList.Remove("_keycloak"); Form1.KeycloakCheckBox.Visible = false; } //stop section foreach (KeyValuePair Service in ServicesList.Reverse()) { //write the service name in the log Console.WriteLine("Stopping: "+Service.Key); //stop the service StopService(Service.Key, 1000); //update the text box Form1.TextDisplay.Text = "Stopping: "+Service.Key; Form1.TextDisplay.Update(); //wait 1 second before Thread.Sleep(TimeSpan.FromSeconds(1)); //displaying end of operation Form1.TextDisplay.Text = "Stopping complete ! "; Form1.TextDisplay.Update(); } Form1.TextDisplay.Text = "Stopping Complete, waiting... "; Form1.TextDisplay.Update(); //wait 3 second before Thread.Sleep(TimeSpan.FromSeconds(3)); //start section foreach (KeyValuePair Service in ServicesList) { //write the service name in the log Console.WriteLine("Starting: "+Service.Key); //start the service StartService(Service.Key, 1000); //update the text box Form1.TextDisplay.Text = "Starting: "+Service.Key; Form1.TextDisplay.Update(); //wait 1 second before Thread.Sleep(TimeSpan.FromSeconds(1)); //check if there is a process still active Process[] localByName = Process.GetProcessesByName(Service.Value); if (localByName.Length > 0) { Form1.TextDisplay.Text = "there is a process running "; Form1.TextDisplay.Update(); Thread.Sleep(TimeSpan.FromSeconds(1)); //loop through every process if multiples foreach (Process process in localByName) { process.Kill(); } Form1.TextDisplay.Text = "kill done "; Form1.TextDisplay.Update(); } //displaying end of operation Form1.TextDisplay.Text = "Starting complete ! "; Form1.TextDisplay.Update(); } } public static void DisplayNetstat() { try { Process[] localByName = Process.GetProcessesByName("TurnaroundService.api"); if (localByName.Length > 0) { Form1.TextDisplay.Text = "there is a service running "; Form1.TextDisplay.Update(); Thread.Sleep(TimeSpan.FromSeconds(2)); localByName[0].Kill(); Form1.TextDisplay.Text = "kill done "; Form1.TextDisplay.Update(); } } catch (Exception e) { Form1.TextDisplay.Text = "Kill failed ! "; Form1.TextDisplay.Update(); Console.WriteLine(e); throw; } } static void Main() { // To customize application configuration such as set high DPI settings or default font, // see https://aka.ms/applicationconfiguration. if (ServicesList.ContainsKey("_keycloak")) { Program.KeycloakHidden = false; Console.WriteLine("keycloak is there"); } if (ServicesList.ContainsKey("_postgresql")) { Program.PostgreSqlHidden = false; Console.WriteLine("postgresql is there"); } ApplicationConfiguration.Initialize(); Application.Run(new Form1()); } }