using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.BL.Entities;
using Tango.Core.Commands;
using Tango.Integration.Operation;
using Tango.PMR.Printing;
using Tango.PPC.Common;
using Tango.PPC.Common.Navigation;
using Tango.PPC.Jobs.AppBarItems;
using Tango.PPC.Jobs.AppButtons;
using Tango.PPC.Jobs.Dialogs;
using Tango.PPC.Jobs.NavigationObjects;
using Tango.PPC.Jobs.Views;
namespace Tango.PPC.Jobs.ViewModels
{
/// <summary>
/// Represents the job progress view model.
/// </summary>
/// <seealso cref="Tango.PPC.Common.PPCViewModel" />
public class JobProgressViewVM : PPCViewModel
{
private StopPrintingButton _stop_job_btn;
private JobHandler _handler;
#region Properties
private Job _job;
/// <summary>
/// Gets or sets the job.
/// </summary>
public Job Job
{
get { return _job; }
set { _job = value; RaisePropertyChangedAuto(); }
}
private RunningJobStatus _runningJobStatus;
/// <summary>
/// Gets or sets the running job status.
/// </summary>
public RunningJobStatus RunningJobStatus
{
get { return _runningJobStatus; }
set { _runningJobStatus = value; RaisePropertyChangedAuto(); }
}
private bool _isDisplayJobOutline;
/// <summary>
/// Gets or sets a value indicating whether to display the job outline.
/// </summary>
public bool IsDisplayJobOutline
{
get { return _isDisplayJobOutline; }
set { _isDisplayJobOutline = value; RaisePropertyChangedAuto(); }
}
private JobTicket _jobOutlineTicket;
/// <summary>
/// Gets or sets the job outline ticket.
/// </summary>
public JobTicket JobOutlineTicket
{
get { return _jobOutlineTicket; }
set { _jobOutlineTicket = value; RaisePropertyChangedAuto(); }
}
#endregion
#region Commands
/// <summary>
/// Gets or sets the go to job command.
/// </summary>
/// <value>
/// The go to job command.
/// </value>
public RelayCommand GoToJobCommand { get; set; }
/// <summary>
/// Gets or sets the display job outline command.
/// </summary>
public RelayCommand DisplayJobOutlineCommand { get; set; }
/// <summary>
/// Gets or sets the hide job outline command.
/// </summary>
public RelayCommand HideJobOutlineCommand { pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.BL;
using Tango.BL.Entities;
using Tango.Integration.Operation;
using Tango.Settings;
using Tango.PPC.Common.Application;
using Tango.Core.DI;
using Tango.PPC.Common;
using System.Windows;
using Tango.Core;
using System.IO;
using Tango.Core.Helpers;
using Tango.PPC.Common.Modules;
using System.Windows.Threading;
using Tango.Transport.Adapters;
using Tango.PMR.Connection;
using Tango.PPC.Common.Connection;
using Tango.SQLExaminer;
using System.Data.SqlClient;
using Tango.BL.Builders;
using Tango.PPC.Common.Threading;
using System.Diagnostics;
using Tango.PPC.Common.EventLogging;
using Tango.BL.Enumerations;
using Tango.PPC.Common.Notifications;
using Tango.PPC.Common.WatchDog;
using Tango.PPC.UI.Dialogs;
using Tango.Core.Threading;
using Tango.PPC.Common.Messages;
using Tango.Core.ExtensionMethods;
using Tango.PPC.Common.Navigation;
using Tango.PPC.Common.Synchronization;
using Tango.Insights;
using System.Threading;
namespace Tango.PPC.UI.PPCApplication
{
/// <summary>
/// Represents the default PPC application manager.
/// </summary>
/// <seealso cref="Tango.Core.ExtendedObject" />
/// <seealso cref="Tango.PPC.Common.Application.IPPCApplicationManager" />
public class DefaultPPCApplicationManager : ExtendedObject, IPPCApplicationManager
{
private List<PPCViewModel> _notifiedViewModels;
private IMachineProvider _machineProvider;
private Machine _machine;
private IDispatcherProvider _dispatcher;
private IEventLogger _eventLogger;
private IPPCModuleLoader _moduleLoader;
private INotificationProvider _notificationProvider;
private IMachineDataSynchronizer _machineDataSynchronizer;
private WatchDogServer _watchdogServer;
private ObservablesContext _machineContext;
private ActionTimer _screenLockTimer;
/// <summary>
/// Occurs when a system restart is required.
/// </summary>
public event EventHandler SystemRestartRequired;
/// <summary>
/// Occurs when the updater utility has failed to perform the last update.
/// </summary>
public event EventHandler UpdaterFailed;
/// <summary>
/// Occurs when the application has started.
/// </summary>
public event EventHandler ApplicationStarted;
/// <summary>
/// Occurs when all PPC modules are ready and initialized.
/// </summary>
public event EventHandler ModulesInitialized;
/// <summary>
/// Occurs when the application is ready and all modules are views are loaded.
/// </summary>
public event EventHandler ApplicationReady;
/// <summary>
/// Occurs when machine setup is required.
/// </summary>
public event EventHandler SetupRequired;
/// <summary>
/// Occurs when the main window content has been rendered.
/// </summary>
public event EventHandler ContentRendered;
/// <summary>
/// Occurs when the application has encountered an error when initializing.
/// </summary>
public event EventHandler<Exception> ApplicationInitializationError;
/// <summary>
/// Gets a value indicating whether the application is shutting down.
/// </summary>
public bool IsShuttingDown { get; private set; }
private bool _isInTechnicianMode;
/// <summary>
/// Gets a value indicating whether the application is in technician mode.
/// </summary>
public bool IsInTechnicianMode
{
get { return _isInTechnicianMode; }
set { _isInTechnicianMode = value; RaisePropertyChangedAuto(); }
}
/// <summary>
/// Gets the application version.
/// </summary>
public Version Version
{
get
{
return AssemblyHelper.GetCurrentAssemblyVersion();
}
}
/// <summary>
/// Gets the application build date.
/// </summary>
public String BuildDate
{
get
{
return AssemblyHelper.GetCurrentAssemblyBuildDate().ToShortDateString();
}
}
/// <summary>
/// Gets the application startup date.
/// </summary>
public DateTime StartUpDate { get; private set; }
/// <summary>
/// Gets a value indicating whether an update has occurred before the application started.
/// </summary>
public bool IsAfterUpdate { get; private set; }
/// <summary>
/// Gets a value indicating whether the updater utility has failed to perform the last update.
/// </summary>
public bool IsUpdateFailed { get; private set; }
private bool _isScreenLocked;
/// <summary>
/// Gets or sets a value indicating whether the screen is currently locked.
/// </summary>
public bool IsScreenLocked
{
get { return _isScreenLocked; }
set { _isScreenLocked = value; RaisePropertyChangedAuto(); }
}
/// <summary>
/// Gets the firmware version.
/// </summary>
public Version FirmwareVersion
{
get
{
return Version.Parse(SettingsManager.Default.GetOrCreate<PPCSettings>().FirmwareVersion);
}
}
/// <summary>
/// Gets or sets the application folder.
/// </summary>
public String StartPath { get; private set; }
/// <summary>
/// Initializes a new instance of the <see cref="DefaultPPCApplicationManager"/> class.
/// </summary>
public DefaultPPCApplicationManager(IMachineProvider machineProvider, IDispatcherProvider dispatcherProvider, IEventLogger eventLogger, IPPCModuleLoader moduleLoader, INotificationProvider notificationProvider, IMachineDataSynchronizer machineDataSynchronizer)
{
StartPath = AssemblyHelper.GetCurrentAssemblyFolder();
_notificationProvider = notificationProvider;
_machineProvider = machineProvider;
_dispatcher = dispatcherProvider;
_eventLogger = eventLogger;
_moduleLoader = moduleLoader;
_machineDataSynchronizer = machineDataSynchronizer;
if (!DesignMode)
{
_notifiedViewModels = new List<PPCViewModel>();
MainWindow.Instance.ContentRendered += (_, __) =>
{
OnMainWindowContentRendered();
};
}
}
/// <summary>
/// Called when the main window content has been rendered
/// </summary>
private void OnMainWindowContentRendered()
{
LogManager.Log("Main window content rendered.");
ContentRendered?.Invoke(this, new EventArgs());
StartApplication();
}
private async void StartApplication()
{
PPCSettings settings = null;
bool initialized = false;
bool isAfterSetup = false;
StartUpDate = DateTime.Now;
await Task.Factory.StartNew(() =>
{
try
{
LogManager.Log("Reading PPC settings...");
settings = SettingsManager.Default.GetOrCreate<PPCSettings>();
LogManager.Log(settings.ToJsonString());
//Start watchdog
_watchdogServer = new WatchDogServer(Application.Current.Dispatcher);
#if !DEBUG
if (settings.EnableWatchDog)
{
_watchdogServer.Start();
}
#endif
LogManager.Log("Reading Core settings...");
var coreSettings = SettingsManager.Default.GetOrCreate<CoreSettings>();
if (!SettingsManager.Default.IsFileExists())
{
LogManager.Log("Settings file does not exists. creating...");
settings.Save();
}
if (App.StartupArgs.Contains("-update_ok"))
{
LogManager.Log("Application started with '-update_ok' startup arguments. The application has been successfully updated.");
if (settings.ApplicationState == ApplicationStates.PreSetup || settings.ApplicationState == ApplicationStates.FactoryRestore)
{
isAfterSetup = true;
LogManager.Log("System restart is required.");
}
else
{
IsAfterUpdate = true;
}
settings.ApplicationState = ApplicationStates.Ready;
settings.Save();
if (isAfterSetup)
{
SystemRestartRequired?.Invoke(this, new EventArgs());
return;
}
}
if (App.StartupArgs.Contains("-update_failed"))
{
LogManager.Log("Application started with '-update_failed' startup arguments. The updater utility has failed.");
IsUpdateFailed = true;
settings.ApplicationState = ApplicationStates.Ready;
settings.Save();
UpdaterFailed?.Invoke(this, new EventArgs());
return;
}
if (settings.ApplicationState == ApplicationStates.Ready)
{
LogManager.Log("Initializing ObservablesStaticCollections...");
ObservablesStaticCollections.Instance.Initialize();
LogManager.Log("Loading machine from database...");
_machineContext = ObservablesContext.CreateDefault();
_machine = new MachineBuilder(_machineContext).SetFirst().WithVersion().WithOrganization().WithConfiguration().WithSpools().WithCats().Build();
}
initialized = true;
}
catch (Exception ex)
{
LogManager.Log(ex, "Application Initialization Error!");
ApplicationInitializationError?.Invoke(this, ex);
return;
}
});
if (initialized)
{
try
{
if (settings.ApplicationState == ApplicationStates.PreSetup || settings.ApplicationState == ApplicationStates.FactoryRestore)
{
LogManager.Log($"The application is in {settings.ApplicationState} state. database initialization skipped. Invoking setup required event!");
SetupRequired?.Invoke(this, new EventArgs());
}
else
{
PostDbInitialize();
}
}
catch (Exception ex)
{
LogManager.Log(ex, "Application Post Initialization Error!");
ApplicationInitializationError?.Invoke(this, ex);
return;
}
}
}
/// <summary>
/// Called when the database has been initialized
/// </summary>
private void PostDbInitialize()
{
LogManager.Log($"Raising {nameof(ApplicationStarted)} event...");
ApplicationStarted?.Invoke(this, new EventArgs());
LogManager.Log("Invoking PPC view models OnApplicationStarted methods...");
foreach (var vm in TangoIOC.Default.GetAllInstancesByBase<PPCViewModel>())
{
if (!_notifiedViewModels.Contains(vm))
{
LogManager.Log($"Invoking {vm.GetType().Name}.OnApplicationStarted...");
vm.OnApplicationStarted();
_notifiedViewModels.Add(vm);
}
}
var internalModules = this.GetType().Assembly.GetTypes().Where(xx => typeof(PPCModuleBase).IsAssignableFrom(xx)).ToList();
LogManager.Log("Waiting for IPPCModuleLoader instance injection...");
TangoIOC.Default.GetInstanceWhenAvailable<IPPCModuleLoader>((loader) =>
{
LogManager.Log("Module loader instance has been registered. Registering for the ModulesLoaded event...");
loader.ModulesLoaded += (x, y) =>
{
LogManager.Log("Loading modules views");
_dispatcher.InvokeBlock(() =>
{
foreach (var module in TangoIOC.Default.GetInstance<IPPCModuleLoader>().UserModules)
{
if (!Views.LayoutView.Instance.NavigationControl.Elements.ToList().Exists(m => m.GetType() == module.MainViewType))
{
try
{
LogManager.Log("Loading module view " + module.Name + "...");
FrameworkElement view = Activator.CreateInstance(module.MainViewType) as FrameworkElement;
SharedUI.Controls.NavigationControl.SetNavigationName(view, module.Name);
Views.LayoutView.Instance.NavigationControl.Elements.Add(view);
}
catch (Exception ex)
{
LogManager.Log(ex, $"Error loading module view for module {module.Name}.");
}
}
}
//Adding internal modules.
LogManager.Log("Loading internal modules...");
foreach (var type in internalModules)
{
var module = Activator.CreateInstance(type) as IPPCModule;
LogManager.Log("Loading module view " + module.Name + "...");
FrameworkElement view = Activator.CreateInstance(module.MainViewType) as FrameworkElement;
SharedUI.Controls.NavigationControl.SetNavigationName(view, module.Name);
Views.LayoutView.Instance.NavigationControl.Elements.Add(view);
_moduleLoader.AllModules.Add(module);
_moduleLoader.UserModules.Add(module);
}
});
LogManager.Log($"{loader.UserModules.Count} modules loaded.");
LogManager.Log($"Invoking {nameof(ModulesInitialized)} event.");
ModulesInitialized?.Invoke(this, new EventArgs());
FinalizeModuleInitialization();
};
});
}
/// <summary>
/// Finalizes the module initialization.
/// </summary>
private void FinalizeModuleInitialization()
{
var settings = SettingsManager.Default.GetOrCreate<PPCSettings>();
LogManager.Log("Finalizing application initialization...");
LogManager.Log("Initializing Machine Provider...");
_machineProvider.Init(_machine, _machineContext);
LogManager.Log("Starting Machine Data Synchronizer...");
_machineDataSynchronizer.IsEnabled = true;
LogManager.Log("Applications initialization completed!");
LogManager.Log("Checking for un-notified PPC view models...");
foreach (var vm in TangoIOC.Default.GetAllInstancesByBase<PPCViewModel>())
{
if (!_notifiedViewModels.Contains(vm))
{
LogManager.Log($"Invoking {vm.GetType().Name}.OnApplicationStarted...");
vm.OnApplicationStarted();
_notifiedViewModels.Add(vm);
}
}
_dispatcher.Invoke(() =>
{
LogManager.Log($"Invoking {nameof(ApplicationReady)} event.");
_eventLogger.Log(EventTypes.APPLICATION_STARTED, "Application Started!");
ApplicationReady?.Invoke(this, new EventArgs());
LogManager.Log("Notifying view models about application ready...");
foreach (var vm in TangoIOC.Default.GetAllInstancesByBase<PPCViewModel>())
{
LogManager.Log($"Invoking {vm.GetType().Name}.OnApplicationReady...");
vm.OnApplicationReady();
}
if (settings.EnableTechnicianModeByDefault)
{
EnterTechnicianMode(false);
}
if (settings.EnableLockScreen)
{
_screenLockTimer = new ActionTimer(settings.LockScreenTimeout);
_screenLockTimer.ResetReplace(ScreenLockTimerAction);
}
TangoMessenger.Default.Register<MachineSettingsSavedMessage>((msg) =>
{
if (_screenLockTimer != null)
{
_screenLockTimer.Dispose();
_screenLockTimer = null;
}
if (settings.EnableLockScreen)
{
_screenLockTimer = new ActionTimer(settings.LockScreenTimeout);
_screenLockTimer.ResetReplace(ScreenLockTimerAction);
}
});
});
}
/// <summary>
/// Shutdown the application.
/// </summary>
public async void ShutDown()
{
if (IsShuttingDown) return;
IsShuttingDown = true;
try
{
LogManager.Log("Shutting down application...");
_watchdogServer.Dispose();
foreach (var vm in TangoIOC.Default.GetAllInstancesByBase<PPCViewModel>())
{
vm.OnApplicationShuttingDown();
}
}
catch { }
try
{
await FinalizeApplication();
}
catch (Exception ex)
{
LogManager.Log(ex, "Error occurred on application shutdown finalization.");
}
Environment.Exit(0);
}
/// <summary>
/// Restarts the application.
/// </summary>
public async void Restart()
{
if (IsShuttingDown) return;
IsShuttingDown = true;
try
{
_dispatcher.Invoke(() =>
{
var nav = TangoIOC.Default.GetInstance<INavigationManager>();
if (nav != null)
{
nav.NavigateTo(NavigationView.RestartingView);
}
});
LogManager.Log("Restarting the application...");
await Task.Delay(8000);
_watchdogServer.Dispose();
foreach (var vm in TangoIOC.Default.GetAllInstancesByBase<PPCViewModel>())
{
try
{
vm.OnApplicationShuttingDown();
}
catch { }
}
}
catch { }
try
{
if (_machineProvider.MachineOperator.State == Transport.TransportComponentState.Connected)
{
_machineProvider.MachineOperator.Adapter.Disconnect().Wait();
}
}
catch { }
try
{
await FinalizeApplication();
}
catch (Exception ex)
{
LogManager.Log(ex, "Error occurred on application shutdown finalization.");
}
Process.Start(Application.ResourceAssembly.Location);
Environment.Exit(0);
}
/// <summary>
/// Runs the updater utility and exits the application.
/// </summary>
public async void UpdateApplication(String updaterPath, String arguments)
{
if (IsShuttingDown) return;
IsShuttingDown = true;
LogManager.Log("Restarting application for update...");
try
{
LogManager.Log("Navigating to restart view...");
_dispatcher.Invoke(() =>
{
var nav = TangoIOC.Default.GetInstance<INavigationManager>();
if (nav != null)
{
nav.NavigateTo(NavigationView.RestartingView);
}
});
LogManager.Log("Waiting 2 seconds...");
await Task.Delay(2000);
try
{
LogManager.Log("Disposing watch dog...");
_watchdogServer.Dispose();
}
catch (Exception ex)
{
LogManager.Log(ex, "Error disposing watch dog.");
}
LogManager.Log("Raising OnApplicationShutDown for all view models...");
foreach (var vm in TangoIOC.Default.GetAllInstancesByBase<PPCViewModel>())
{
try
{
vm.OnApplicationShuttingDown();
}
catch (Exception ex)
{
LogManager.Log(ex, $"Error on {vm.GetType().Name}.OnApplicationShutDown().");
}
}
}
catch { }
try
{
LogManager.Log("Saving application settings...");
SettingsManager.Default.GetOrCreate<PPCSettings>().PreviousApplicationVersion = Version.ToString();
SettingsManager.Default.Save();
}
catch (Exception ex)
{
LogManager.Log(ex, "Error saving application settings.");
}
try
{
await FinalizeApplication();
}
catch (Exception ex)
{
LogManager.Log(ex, "Error occurred on application shutdown finalization.");
}
LogManager.Log($"Executing '{updaterPath}' with arguments '{arguments}'...");
Process p = new Process();
p.StartInfo.FileName = updaterPath;
p.StartInfo.Arguments = arguments;
p.StartInfo.LoadUserProfile = true;
p.StartInfo.UseShellExecute = true;
p.Start();
LogManager.Log("Terminating application...");
Environment.Exit(0);
}
/// <summary>
/// Enteres the application technician mode.
/// </summary>
public async void EnterTechnicianMode(bool displayNotification = true)
{
if (displayNotification)
{
var vm = await _notificationProvider.ShowDialog<TechnicianModeLoginViewVM>();
if (vm.DialogResult)
{
if (vm.Password == "Aa123456")
{
IsInTechnicianMode = true;
_moduleLoader.AllModules.ToList().ForEach(x => x.OnTechnicianEntered());
await _notificationProvider.ShowInfo("Technician mode is now enabled.");
}
else
{
await _notificationProvider.ShowError("Invalid technician mode password.");
EnterTechnicianMode();
}
}
}
else
{
IsInTechnicianMode = true;
_moduleLoader.AllModules.ToList().ForEach(x => x.OnTechnicianEntered());
}
}
/// <summary>
/// Exits the application technician mode.
/// </summary>
public void ExitTechnicianMode()
{
IsInTechnicianMode = false;
_moduleLoader.AllModules.ToList().ForEach(x => x.OnTechnicianExited());
_notificationProvider.ShowInfo("Technician mode is now disabled.");
}
/// <summary>
/// Invokes a dialog for entering a password and releasing the screen lock.
/// </summary>
public async void ReleaseScreenLock()
{
if (IsScreenLocked)
{
var vm = await _notificationProvider.ShowDialog<ScreenLockViewVM>();
if (vm.DialogResult)
{
if (vm.Password == SettingsManager.Default.GetOrCreate<PPCSettings>().LockScreenPassword)
{
IsScreenLocked = false;
ResetScreenLockTimer();
}
}
}
}
public void ResetScreenLockTimer()
{
if (_screenLockTimer != null)
{
_screenLockTimer.ResetReplace(ScreenLockTimerAction);
}
}
private void ScreenLockTimerAction()
{
IsScreenLocked = true;
}
public void SetWindowState(WindowState state)
{
InvokeUI(() =>
{
MainWindow.Instance.WindowState = state;
});
}
private Task FinalizeApplication()
{
LogManager.Log("Finalizing application...");
return LimitedTimeTask.StartNew(() =>
{
try
{
LogManager.Log("Flushing machine events...");
_eventLogger.Log(EventTypes.APPLICATION_TERMINATED, "User Interface Terminated.");
_eventLogger.FlushAll();
}
catch (Exception ex)
{
LogManager.Log(ex, "Error flushing machine events.");
}
try
{
LogManager.Log("Disposing insights manager (max 40 seconds to complete)...");
Stopwatch watch = new Stopwatch();
watch.Start();
var frame = InsightsFrame.CreateEmpty(DateTime.UtcNow);
InsightsManager.Default.InsertFrame(frame);
InsightsManager.Default.Dispose();
watch.Stop();
LogManager.Log($"Insights manager disposed after {(int)watch.Elapsed.TotalSeconds} seconds.");
}
catch (Exception ex)
{
LogManager.Log(ex, "Error disposing insights manager.");
}
}, TimeSpan.FromSeconds(40));
}
}
}