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);
        }
Exemple #2
0
        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 { }
                {
                }
            }
        }