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); #region Ticketübersicht private TrayTicketNotificationManager _ticketTrayNotification; private TileScope? _pendingTicketOverviewScope; #endregion 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() { "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; if (TryHandleTicketOverviewNotificationClick(searchView)) 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); } } #region Ticketübersicht private bool TryHandleTicketOverviewNotificationClick(SearchPageView searchView) { if (searchView == null) return false; if (!HasPendingTicketOverviewNotification()) return false; if (!searchView.IsVisible) searchView.ActivateSearchView(); else searchView.BringToFrontPreserveState(); searchView.ShowTicketOverviewPaneForScope(PendingTicketOverviewScope); ClearTicketOverviewTrayNotification(); return true; } 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; #endregion 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; } } }