Files
C4IT-F4SD-Client/FasdDesktopUi/App.xaml.cs
2026-02-03 15:54:56 +01:00

536 lines
20 KiB
C#

using C4IT.FASD.Base;
using C4IT.FASD.Cockpit.Communication;
using C4IT.FASD.Security;
using C4IT.Graphics;
using C4IT.Logging;
using C4IT.MultiLanguage;
using FasdDesktopUi.Basics;
using FasdDesktopUi.Basics.Helper;
using FasdDesktopUi.Basics.Models;
using FasdDesktopUi.Basics.Services.Models;
using FasdDesktopUi.Pages.CustomMessageBox;
using FasdDesktopUi.Pages.PhoneSettingsPage;
using FasdDesktopUi.Pages.SearchPage;
using FasdDesktopUi.Pages.SettingsPage;
using FasdDesktopUi.Pages.ShortCutPage;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows;
using System.Windows.Input;
using static C4IT.Logging.cLogManager;
namespace FasdDesktopUi
{
public partial class App : Application
{
static public string PhoneMonitorPipeName;
static public Mutex AppMutex = null;
static public string PipeName = "";
static public System.Windows.Forms.ToolStripItem M42OptionMenuItem = null;
public System.Windows.Forms.NotifyIcon notifyIcon = new System.Windows.Forms.NotifyIcon() { Text = $"First Aid Service Desk" };
public bool UseOsLanguage = string.IsNullOrEmpty(cFasdCockpitConfig.Instance.SelectedLanguage);
private TrayTicketNotificationManager _ticketTrayNotification;
private TileScope? _pendingTicketOverviewScope;
private async void Application_Startup(object sender, StartupEventArgs e)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
InitializeLogger();
/* Attach debugger befor start
Console.WriteLine("Waiting for debugger to attach");
while (!Debugger.IsAttached)
{
Thread.Sleep(100);
}
Console.WriteLine("Debugger attached");
*/
Assembly assembly = Assembly.GetExecutingAssembly();
var ProductName = FileVersionInfo.GetVersionInfo(assembly.Location).ProductName;
var attribute = (GuidAttribute)assembly.GetCustomAttributes(typeof(GuidAttribute), true)[0];
var AssemblyGuid = attribute.Value;
string MutexName = ProductName + AssemblyGuid.ToString();
var SessionId = 0;
try
{
SessionId = Process.GetCurrentProcess().SessionId;
}
catch { }
PipeName = MutexName + $".pipe.{SessionId}";
PhoneMonitorPipeName = PipeName + ".PhoneMonitor." + Guid.NewGuid().ToString();
if (e.Args.Length > 0)
{
bool shouldShutdown = cAppStartUp.ProcessCommandLine(e.Args);
if (shouldShutdown)
{
Current.Shutdown();
return;
}
}
try
{
AppMutex = new Mutex(false, MutexName);
if (!AppMutex.WaitOne(0))
{
LogEntry("Application already started, exiting...", LogLevels.Info);
AppMutex.Dispose();
AppMutex = null;
Current.Shutdown();
return;
}
}
catch (Exception E)
{
LogEntry("Cannot create application mutex, exiting...", LogLevels.Fatal);
LogException(E);
Current.Shutdown();
return;
}
cF4sdPipeClient.RegisterProtocol(cAppStartUp.constUrlProtocol, cAppStartUp.constUrlCommand);
cMultiLanguageSupport.CurrentLanguage = cFasdCockpitConfig.Instance.SelectedLanguage;
try
{
FasdSecurity.Init();
PrivateSecurePassword.Init();
}
catch (Exception E)
{
LogException(E);
MessageBox.Show(cMultiLanguageSupport.GetItem("App.Startup.SecurityInitFailed.Text"), cMultiLanguageSupport.GetItem("App.Startup.SecurityInitFailed.Caption"), MessageBoxButton.OK, MessageBoxImage.Error);
Current.Shutdown();
}
InitializeNotifyIcon();
//CustomMessageBox.ShowCustomContent("Close case", enumHealthCardStateLevel.None, null, true, new CloseCaseDialogWithTicket());
await cAppStartUp.StartAsync(e.Args);
notifyIcon.Visible = true;
}
catch (Exception E)
{
LogException(E);
}
finally
{
Mouse.OverrideCursor = null;
LogMethodEnd(CM);
}
}
#region Logger
private void InitializeLogger()
{
cLogManagerFile.CreateInstance(false, SubFolder: "Logs", DebugFlags: new List<string>() { "apivalues", "apitiming" });
cFasdCockpitCommunicationBase.Debug_apiValues = cLogManager.Instance.CheckDebugFlag("apivalues");
cFasdCockpitCommunicationBase.Debug_apiTiming = cLogManager.Instance.CheckDebugFlag("apitiming");
cLogManager.DefaultLogger.LogAssemblyInfo();
Dispatcher.UnhandledException += Dispatcher_UnhandledException;
AppDomain.CurrentDomain.UnhandledException += (o, e) => LogException((Exception)e.ExceptionObject, LogLevels.Fatal);
}
private void Dispatcher_UnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
LogException(e.Exception, LogLevels.Error);
e.Handled = true;
}
#endregion
#region NotifyIcon
public static void HideAllSettingViews()
{
SettingsPageView.Instance?.Hide();
}
private void NotifyIcon_Click(object sender, EventArgs e)
{
try
{
if (e is System.Windows.Forms.MouseEventArgs mouseEventArgs)
if (mouseEventArgs.Button == System.Windows.Forms.MouseButtons.Right)
return;
var searchView = SearchPageView.Instance;
if (searchView == null)
return;
var hasNotification = HasPendingTicketOverviewNotification();
if (hasNotification)
{
if (!searchView.IsVisible)
searchView.ActivateSearchView();
else
searchView.BringToFrontPreserveState();
searchView.ShowTicketOverviewPaneForScope(PendingTicketOverviewScope);
ClearTicketOverviewTrayNotification();
return;
}
#if isDemo
if (searchView.IsVisible)
{
searchView.Hide();
return;
}
if (!searchView.IsVisible)
searchView.ActivateSearchView();
else
searchView.BringToFrontPreserveState();
searchView.ShowTicketOverviewPane();
#else
if (SearchPageView.Instance.IsVisible)
SearchPageView.Instance.Hide();
else
SearchPageView.Instance.ActivateSearchView();
#endif
}
catch (Exception E)
{
LogException(E);
}
}
private void InitializeNotifyIcon()
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
NotifyerSupport.LoadSetFromResource("Default", "FasdDesktopUi.Resources.logo_FASD.ico");
NotifyerSupport.LoadSetFromResource("StartUp", "FasdDesktopUi.Resources.logo_F4SD_flip.ico");
NotifyerSupport.LoadSetFromResource("OverlayOffline", "FasdDesktopUi.Resources.StateOverlays.Offline", NoRefresh: true)?.CreateSizeMap(0.45f);
NotifyerSupport.RegisterNotifyControl(notifyIcon);
NotifyerSupport.SetNotifyIcon("StartUp");
var assemblyVersion = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).ProductVersion;
notifyIcon.Text += " version " + assemblyVersion;
_ticketTrayNotification = new TrayTicketNotificationManager(notifyIcon);
_ticketTrayNotification.CaptureBaseTooltip();
_ticketTrayNotification.ApplyTooltip();
notifyIcon.Click += NotifyIcon_Click;
notifyIcon.BalloonTipClicked += NotifyIcon_BalloonTipClicked;
SetUpNotifyIconLanguageOption();
notifyIcon.ContextMenuStrip = new System.Windows.Forms.ContextMenuStrip() { Visible = true };
notifyIcon.ContextMenuStrip.Items.Add(SetUpNotifyIconLanguageOption());
notifyIcon.ContextMenuStrip.Items.Add(cMultiLanguageSupport.GetItem("Menu.Options"), null, NotifyIconOptions_Click);
M42OptionMenuItem = notifyIcon.ContextMenuStrip.Items.Add(cMultiLanguageSupport.GetItem("M42Settings.SystemTray"), null, (sender, e) =>
{
if (cFasdCockpitCommunicationBase.CockpitUserInfo == null)
return;
M42SettingsPageView.Instance.Show();
});
M42OptionMenuItem.Visible = false;
notifyIcon.ContextMenuStrip.Items.Add(cMultiLanguageSupport.GetItem("PhoneSettings.SystemTray"), null, (sender, e) =>
{
PhoneSettingsPage.Instance.Show();
});
notifyIcon.ContextMenuStrip.Items.Add(new System.Windows.Forms.ToolStripSeparator());
notifyIcon.ContextMenuStrip.Items.Add(cMultiLanguageSupport.GetItem("Menu.KeyBoardShortcuts"), null, (sender, e) =>
{
ShortCutPageView.Instance.Show();
});
notifyIcon.ContextMenuStrip.Items.Add(new System.Windows.Forms.ToolStripSeparator());
notifyIcon.ContextMenuStrip.Items.Add(cMultiLanguageSupport.GetItem("Menu.About"), null, NotifyIconAbout_Click);
notifyIcon.ContextMenuStrip.Items.Add(new System.Windows.Forms.ToolStripSeparator());
notifyIcon.ContextMenuStrip.Items.Add(cMultiLanguageSupport.GetItem("Menu.Restart"), null, NotifyIconRestart_Click);
notifyIcon.ContextMenuStrip.Items.Add(cMultiLanguageSupport.GetItem("Menu.Quit"), null, NotifyIconQuit_Click);
}
catch (Exception E)
{
LogException(E);
}
finally
{
LogMethodEnd(CM);
}
}
private void NotifyIcon_BalloonTipClicked(object sender, EventArgs e)
{
try
{
SearchPageView.Instance?.BringToFrontPreserveState();
SearchPageView.Instance?.ShowTicketOverviewPaneForScope(PendingTicketOverviewScope);
ClearTicketOverviewTrayNotification();
}
catch (Exception E)
{
LogException(E);
}
}
private bool HasPendingTicketOverviewNotification()
{
return _ticketTrayNotification?.HasNotification ?? false;
}
public void ShowTicketOverviewTrayNotification(string message)
{
try
{
_ticketTrayNotification?.Show(message);
}
catch (Exception ex)
{
LogException(ex);
}
}
public void ClearTicketOverviewTrayNotification()
{
try
{
_pendingTicketOverviewScope = null;
_ticketTrayNotification?.Clear();
}
catch (Exception ex)
{
LogException(ex);
}
}
public void SetTicketOverviewNotificationScope(TileScope? scope)
{
_pendingTicketOverviewScope = scope;
}
public TileScope? PendingTicketOverviewScope => _pendingTicketOverviewScope;
private System.Windows.Forms.ToolStripItem SetUpNotifyIconLanguageOption()
{
try
{
var output = new System.Windows.Forms.ToolStripMenuItem() { Text = cMultiLanguageSupport.GetItem("Menu.SelectLanguage") };
var languages = cMultiLanguageSupport.GetSupportedLanguages();
var stripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
var defaultFormat = cMultiLanguageSupport.GetItem("Menu.SelectLanguage.Default");
stripMenuItem.Text = string.Format(defaultFormat, cMultiLanguageSupport.GetOsDefault());
stripMenuItem.Image = cMultiLanguageSupport.GetImage(".");
stripMenuItem.Click += ToolStripMenuLanguage_Click;
if (UseOsLanguage)
stripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
output.DropDownItems.Add(stripMenuItem);
foreach (var Entry in languages)
{
stripMenuItem = new System.Windows.Forms.ToolStripMenuItem
{
Text = Entry,
Tag = Entry,
Image = cMultiLanguageSupport.GetImage(Entry)
};
stripMenuItem.Click += ToolStripMenuLanguage_Click;
if (!UseOsLanguage && (cMultiLanguageSupport.CurrentLanguage == Entry))
stripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
output.DropDownItems.Add(stripMenuItem);
}
return output;
}
catch (Exception E)
{
LogException(E);
}
return null;
}
private void ToolStripMenuLanguage_Click(object sender, EventArgs e)
{
var OldLanguage = cMultiLanguageSupport.CurrentLanguage;
string NewLanguage = null;
if (sender is System.Windows.Forms.ToolStripMenuItem selectedLanguageStripMenuItem)
{
if (selectedLanguageStripMenuItem.OwnerItem is System.Windows.Forms.ToolStripMenuItem parentStripMenuItem)
{
foreach (System.Windows.Forms.ToolStripMenuItem Entry in parentStripMenuItem.DropDownItems)
{
Entry.Checked = Entry == selectedLanguageStripMenuItem;
}
}
if (selectedLanguageStripMenuItem.Tag is string stripMenuItemTag)
{
if (!string.IsNullOrWhiteSpace(stripMenuItemTag))
NewLanguage = stripMenuItemTag;
}
}
UseOsLanguage = NewLanguage == null;
cMultiLanguageSupport.CurrentLanguage = NewLanguage;
cFasdCockpitConfig.Instance.SelectedLanguage = NewLanguage;
cFasdCockpitConfig.Instance.Save("SelectedLanguage");
if (OldLanguage == NewLanguage)
return;
//var dialogResult = MessageBox.Show(cMultiLanguageSupport.GetItem("Menu.SelectLanguage.RestartDialog.Text"), cMultiLanguageSupport.GetItem("Menu.SelectLanguage.RestartDialog.Caption"), MessageBoxButton.YesNo, MessageBoxImage.Information);
var dialogResult = CustomMessageBox.Show(cMultiLanguageSupport.GetItem("Menu.SelectLanguage.RestartDialog.Text"), cMultiLanguageSupport.GetItem("Menu.SelectLanguage.RestartDialog.Caption"), enumHealthCardStateLevel.Info, null, true);
if (dialogResult == true)
{
System.Windows.Forms.Application.Restart();
Current.Shutdown();
}
}
private void NotifyIconOptions_Click(object sender, EventArgs e)
{
try
{
var settingsView = SettingsPageView.Create();
if (settingsView.IsVisible)
settingsView.Hide();
else
settingsView.Show();
}
catch (Exception E)
{
LogException(E);
}
}
private void NotifyIconAbout_Click(object sender, EventArgs e)
{
var assemblyVersion = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).ProductVersion;
var messageText = cMultiLanguageSupport.GetItem("Menu.TrademarkNotice");
CustomMessageBox.Show(messageText, $"First Aid Service Desk ({assemblyVersion})", enumHealthCardStateLevel.Info);
}
private async void NotifyIconRestart_Click(object sender, EventArgs e)
{
try
{
var shouldRestart = await cSupportCaseDataProvider.SupportTicketActiveNoticeAsync();
if (!shouldRestart)
return;
System.Windows.Forms.Application.Restart();
Current.Shutdown();
}
catch (Exception E)
{
LogException(E);
}
}
private async void NotifyIconQuit_Click(object sender, EventArgs e)
{
try
{
var shouldQuit = await cSupportCaseDataProvider.SupportTicketActiveNoticeAsync();
if (!shouldQuit)
return;
Current.Shutdown();
}
catch (Exception E)
{
LogException(E);
}
}
#endregion
private async void Application_Exit(object sender, ExitEventArgs e)
{
cF4sdUserInfo userInfo = null;
ConfiguredTaskAwaitable? closeUserSessionTask = null;
lock (cFasdCockpitCommunicationBase.CockpitUserInfoLock)
{
userInfo = cFasdCockpitCommunicationBase.CockpitUserInfo;
}
if (userInfo?.Id.Equals(Guid.Empty) is false)
{
closeUserSessionTask = cFasdCockpitCommunicationBase.Instance?.CloseUserSession(cFasdCockpitConfig.SessionId).ConfigureAwait(false);
}
await cFasdCockpitCommunicationBase.Instance.TerminateAsync();
if (notifyIcon != null)
{
try
{
cConnectionStatusHelper.Instance.IsActive = false;
notifyIcon.Visible = false;
notifyIcon.Dispose();
cAppStartUp.Terminate();
}
catch { }
}
if (AppMutex != null)
{
try
{
AppMutex.ReleaseMutex();
}
catch { }
try
{
AppMutex.Dispose();
}
catch { }
}
try
{
var _now = DateTime.UtcNow;
bool _validSend = true;
while ((DateTime.UtcNow - _now).TotalSeconds < 6 && _validSend)
_validSend = cF4sdPipeClient.Send("STOP", PhoneMonitorPipeName);
}
catch { }
if (closeUserSessionTask is ConfiguredTaskAwaitable _t)
await _t;
}
}
}