Files
BeWoPlaner/BeWoLauncher/Logic/Controller/ProcessController.cs

220 lines
7.0 KiB
C#
Raw Normal View History

using BeWoLauncher.Logic.Utils;
using BeWoLauncher.ServiceProxy;
using BS.SharedLauncher.Information;
using System;
using System.Diagnostics;
using System.IO;
using System.IO.Pipes;
using System.Threading;
using System.Windows;
using System.Windows.Threading;
namespace BeWoLauncher.Logic.Controller
{
public static class ProcessController
{
private static Process PlanerProcess { get; set; }
public static Application Current => Application.Current;
public static LauncherApp CurrentLauncher => Current as LauncherApp;
2024-05-24 13:55:00 +02:00
public static bool Running { get; set; }
static ProcessController()
{
Running = true;
}
internal static void CheckForOtherInstance()
{
string procName = Process.GetCurrentProcess().ProcessName;
Process[] processes = Process.GetProcessesByName(procName);
2024-05-24 13:55:00 +02:00
if (processes.Length > 1)
2024-05-24 13:55:00 +02:00
{
HandleProzessAlreadyRunning(false);
return;
}
Process[] processes2 = Process.GetProcessesByName("BeWoPlaner");
if (processes2.Length > 0)
{
HandleProzessAlreadyRunning(false);
return;
}
}
internal static void HandleProzessAlreadyRunning(bool letUserKill)
{
#if DEBUG
letUserKill = true;
#endif
if (letUserKill)
{
string message = "Möchten Sie es schließen? Dadurch können nicht gespeicherte Daten verloren gehen.";
string caption = "BeWo Anwendung läuft bereits. ";
2024-05-24 13:55:00 +02:00
var result = MessageBox.Show(message, caption, MessageBoxButton.YesNo);
2024-05-24 13:55:00 +02:00
if (result == MessageBoxResult.Yes)
{
var own_process_id = Process.GetCurrentProcess().Id;
GenericTextLogger.Post($"Beende alle BeWo Prozesse außer PID {own_process_id}");
KillAllPlanerProcess(own_process_id);
}
else
{
StartLauncherShutdown();
}
}
else
{
string message = "BeWoPlaner Anwendung läuft bereits.";
string caption = "Kann BeWoLauncher nicht starten";
MessageBox.Show(message, caption);
StartLauncherShutdown();
}
}
internal static void StartLauncher()
{
CheckForOtherInstance();
LauncherServiceFacade.UpdateServerAddresses();
}
internal static void StartLauncherShutdown()
{
2024-05-24 13:55:00 +02:00
if (!Running)
return;
Running = false;
GenericTextLogger.Post("Schließe Launcher Prozess...");
Current.Shutdown();
}
internal static void StartPlanerProcess()
{
// based on https://docs.microsoft.com/en-us/dotnet/standard/io/how-to-use-anonymous-pipes-for-local-interprocess-communication?redirectedfrom=MSDN
PlanerProcess = new Process();
PlanerProcess.StartInfo.FileName = LauncherPaths.GetPlanerExePath();
PlanerProcess.EnableRaisingEvents = true;
PlanerProcess.Exited += PlanerProcess_Exit;
using (AnonymousPipeServerStream pipeServer = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.Inheritable))
{
PlanerProcess.StartInfo.Arguments = pipeServer.GetClientHandleAsString();
PlanerProcess.StartInfo.UseShellExecute = false;
PlanerProcess.StartInfo.CreateNoWindow = false;
PlanerProcess.StartInfo.RedirectStandardOutput = true;
PlanerProcess.OutputDataReceived += MessageFromPlanerClient;
PlanerProcess.Start();
2024-05-24 13:55:00 +02:00
GenericTextLogger.Post($"Launcher Start: {PlanerProcess.StartInfo.FileName}");
PlanerProcess.BeginOutputReadLine();
pipeServer.DisposeLocalCopyOfClientHandle();
try
{
using (StreamWriter sw = new StreamWriter(pipeServer))
{
var signal = new string[] { "C-137", "C-131" };
sw.AutoFlush = true;
SendInfo(sw, signal[0], pipeServer);
SessionInformation.Connection.ToList().ForEach(info => SendInfo(sw, info, pipeServer));
SessionInformation.Login.ToList().ForEach(info => SendInfo(sw, info, pipeServer));
SessionInformation.Session.ToList().ForEach(info => SendInfo(sw, info, pipeServer));
SendInfo(sw, signal[1], pipeServer);
}
}
catch (IOException ex)
{
}
}
}
internal static void SendInfo(StreamWriter sw, string info, AnonymousPipeServerStream pipe)
{
sw.WriteLine(info);
pipe.WaitForPipeDrain();
}
2024-05-24 13:55:00 +02:00
internal static void KillOwnPlanerProcess()
{
if (PlanerProcess is null)
return;
if (PlanerProcess.HasExited)
return;
PlanerProcess.CloseMainWindow();
PlanerProcess.Close();
PlanerProcess = null;
}
internal static void KillAllPlanerProcess(int? own_id)
{
foreach (var process in Process.GetProcesses())
{
2024-05-24 13:55:00 +02:00
if (own_id.HasValue)
{
if (process.Id == own_id.Value)
continue;
}
if (process.ProcessName.Contains("BeWoPlaner"))
{
process.Kill();
}
}
}
internal static void PlanerProcess_Exit(object sender, EventArgs e)
{
// ExitCode Übersicht:
// 100 - Nutzer hat Logout in Core gedrückt
// 0 - Nutzer hat Fenster geschlossen
// 1 - Proess über TaskManager gekillt
if (PlanerProcess.ExitCode == 100)
{
2024-05-24 13:55:00 +02:00
GenericTextLogger.Post("Planer Prozess beendet mit ExitCode 100. Starte Launcher neu.");
CurrentLauncher.Dispatcher.BeginInvoke(DispatcherPriority.Render, (Action)delegate
{
Thread.Sleep(500);
ViewController.RestartView();
});
return;
}
CurrentLauncher.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)StartLauncherShutdown);
}
private static void MessageFromPlanerClient(object sender, DataReceivedEventArgs args)
{
var data = args.Data;
if (data == "GUI geladen")
{
ViewController.CurrentWindow.Dispatcher.BeginInvoke(DispatcherPriority.Render, (Action)(() => ViewController.CurrentWindow.Hide()));
}
}
}
}