// Copyright (c) Microsoft Corporation // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Threading; using System.Windows; using Common.UI; using ManagedCommon; using WorkspacesEditor.Utils; using WorkspacesEditor.ViewModels; namespace WorkspacesEditor { /// /// Interaction logic for App.xaml /// public partial class App : Application, IDisposable { private static Mutex _instanceMutex; public static WorkspacesEditorIO WorkspacesEditorIO { get; private set; } private MainWindow _mainWindow; private MainViewModel _mainViewModel; public static ThemeManager ThemeManager { get; set; } private bool _isDisposed; public App() { WorkspacesEditorIO = new WorkspacesEditorIO(); } private void OnStartup(object sender, StartupEventArgs e) { Logger.InitializeLogger("\\Workspaces\\Logs"); AppDomain.CurrentDomain.UnhandledException += OnUnhandledException; const string appName = "Local\\PowerToys_Workspaces_Editor_InstanceMutex"; bool createdNew; _instanceMutex = new Mutex(true, appName, out createdNew); if (!createdNew) { Logger.LogWarning("Another instance of Workspaces Editor is already running. Exiting this instance."); _instanceMutex = null; Shutdown(0); return; } if (PowerToys.GPOWrapperProjection.GPOWrapper.GetConfiguredWorkspacesEnabledValue() == PowerToys.GPOWrapperProjection.GpoRuleConfigured.Disabled) { Logger.LogWarning("Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator."); Shutdown(0); return; } var args = e?.Args; int powerToysRunnerPid; if (args?.Length > 0) { _ = int.TryParse(args[0], out powerToysRunnerPid); Logger.LogInfo($"WorkspacesEditor started from the PowerToys Runner. Runner pid={powerToysRunnerPid}"); RunnerHelper.WaitForPowerToysRunner(powerToysRunnerPid, () => { Logger.LogInfo("PowerToys Runner exited. Exiting WorkspacesEditor"); Dispatcher.Invoke(Shutdown); }); } ThemeManager = new ThemeManager(this); if (_mainViewModel == null) { _mainViewModel = new MainViewModel(WorkspacesEditorIO); } var parseResult = WorkspacesEditorIO.ParseWorkspaces(_mainViewModel); // normal start of editor if (_mainWindow == null) { _mainWindow = new MainWindow(_mainViewModel); } // reset main window owner to keep it on the top _mainWindow.ShowActivated = true; _mainWindow.Topmost = true; _mainWindow.Show(); // we can reset topmost flag after it's opened _mainWindow.Topmost = false; } private void OnExit(object sender, ExitEventArgs e) { if (_instanceMutex != null) { _instanceMutex.ReleaseMutex(); } Dispose(); Environment.Exit(0); } private void OnUnhandledException(object sender, UnhandledExceptionEventArgs args) { Logger.LogError("Unhandled exception occurred", args.ExceptionObject as Exception); } protected virtual void Dispose(bool disposing) { if (!_isDisposed) { if (disposing) { ThemeManager?.Dispose(); _instanceMutex?.Dispose(); } _isDisposed = true; } } public void Dispose() { // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method Dispose(disposing: true); GC.SuppressFinalize(this); } } }