public static bool MessageHandler(ref Message m) { if (m.Msg == WM_ENDSESSION || (m.Msg == WM_QUERYENDSESSION && ShutdownInitiated)) { m.Result = new IntPtr(ENDSESSION_CLOSEAPP); return(true); } else if (m.Msg == WM_QUERYENDSESSION) { //system getting ready to shut down //individual *forms* receive this message, so we must protect against a race condition using (var shutdownMutex = new ScopedMutex(_appName + "{EA433526-9724-43FD-B175-6EA7BA7517A4}")) { if (ShutdownInitiated) { m.Result = new IntPtr(ENDSESSION_CLOSEAPP); return(true); } ShutdownInitiated = true; var recoveryMan = new RecoveryManager(); recoveryMan.CreateRecoveryData(recoveryMan.UnsafeShutdownPath); ShutdownDumpComplete.Set(); m.Result = new IntPtr(ENDSESSION_CLOSEAPP); return(true); } } return(false); }
public WindowManager() { var args = Environment.GetCommandLineArgs().Skip(1).ToArray(); //Create recovery manager _recoveryManager.RegisterRecovery(); //Check if recovery needed if (args.Length >= 2 && args[0] == "/recover") { var recoveryPath = args[1]; _recoveryManager.Recover(recoveryPath); try { Directory.Delete(recoveryPath, true); } catch { } } else { if (_recoveryManager.UnsafeShutdown) { _recoveryManager.Recover(_recoveryManager.UnsafeShutdownPath); } //save unsafe shutdown data until a new backup exists or we exit cleanly //_recoveryManager.CleanUp(); foreach (var path in args) { OpenInNewWindow(path); } } //Create a backup every x seconds for recovery purposes, but only after any recovery finishes var backupTimer = new System.Threading.Timer((o) => { _recoveryManager.CreateRecoveryData(_recoveryManager.UnsafeShutdownPath); }, null, 10 * 1000, 60 * 1000); //new window handler for default entity if (!WindowQueue.Any()) { CreateNewWindow(); } var waitHandles = new WaitHandle[] { CreateWindowEvent, AllWindowsClosed, CloseAll }; bool done = false; AppDomain.CurrentDomain.ProcessExit += (sender, e) => { while (!done) { ; } }; while (!done) { switch (WaitHandle.WaitAny(waitHandles)) { case 0: var thread = new Thread(() => { Interlocked.Increment(ref ThreadCounter); if (WindowQueue.Any()) { using (var form = new Form1()) { _activeWindows.Add(form); var handler = WindowQueue.Dequeue(); handler.BeforeShow?.Invoke(form); form.StartAction = handler.AfterShow; form.ShowDialog(); _activeWindows.Remove(form); } } if (Interlocked.Decrement(ref ThreadCounter) == 0) { AllWindowsClosed.Set(); } }); thread.SetApartmentState(ApartmentState.STA); thread.Start(); break; case 1: done = true; break; case 2: done = true; break; } } //Delete the unsafe shutdown folder if this is a clean shutdown if (!RecoveryManager.ShutdownInitiated && Directory.Exists(_recoveryManager.UnsafeShutdownPath)) { try { Directory.Delete(_recoveryManager.UnsafeShutdownPath, true); } catch { } { } } }