diff --git a/ShareX.HelpersLib/Native/NativeEnums.cs b/ShareX.HelpersLib/Native/NativeEnums.cs
index cf501f446..b9a569f90 100644
--- a/ShareX.HelpersLib/Native/NativeEnums.cs
+++ b/ShareX.HelpersLib/Native/NativeEnums.cs
@@ -3131,4 +3131,42 @@ public enum CreateProcessFlags : uint
PROFILE_SERVER = 0x40000000,
CREATE_IGNORE_SYSTEM_DEFAULT = 0x80000000,
}
+
+ [Flags]
+ public enum RegisterApplicationRestartFlags : uint
+ {
+ ///
+ /// Do not restart the process if it terminates due to an unhandled exception.
+ ///
+ RESTART_NO_CRASH = 1,
+ ///
+ /// Do not restart the process if it terminates due to the application not responding.
+ ///
+ RESTART_NO_HANG = 2,
+ ///
+ /// Do not restart the process if it terminates due to the installation of an update.
+ ///
+ RESTART_NO_PATCH = 4,
+ ///
+ /// Do not restart the process if the computer is restarted as the result of an update.
+ ///
+ RESTART_NO_REBOOT = 8
+ }
+
+ [Flags]
+ public enum EndSessionReasons : uint
+ {
+ ///
+ /// The application is using a file that must be replaced, the system is being serviced, or system resources are exhausted.
+ ///
+ ENDSESSION_CLOSEAPP = 0x1,
+ ///
+ /// The application is forced to shut down.
+ ///
+ ENDSESSION_CRITICAL = 0x40000000,
+ ///
+ /// The user is logging off.
+ ///
+ ENDSESSION_LOGOFF = 0x80000000
+ }
}
\ No newline at end of file
diff --git a/ShareX.HelpersLib/Native/NativeMethods.cs b/ShareX.HelpersLib/Native/NativeMethods.cs
index 91065e23c..46435842b 100644
--- a/ShareX.HelpersLib/Native/NativeMethods.cs
+++ b/ShareX.HelpersLib/Native/NativeMethods.cs
@@ -316,6 +316,9 @@ public static extern bool CreateProcess(string lpApplicationName, string lpComma
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsWow64Process([In] IntPtr hProcess, [Out] out bool lpSystemInfo);
+ [DllImport("kernel32.dll", PreserveSig = false)]
+ public static extern void RegisterApplicationRestart(string pwzCommandline, RegisterApplicationRestartFlags dwFlags);
+
#endregion kernel32.dll
#region gdi32.dll
diff --git a/ShareX/Forms/ActionsToolbarForm.cs b/ShareX/Forms/ActionsToolbarForm.cs
index deab3c559..4c2d4291f 100644
--- a/ShareX/Forms/ActionsToolbarForm.cs
+++ b/ShareX/Forms/ActionsToolbarForm.cs
@@ -404,7 +404,8 @@ private void tslTitle_MouseDown(object sender, MouseEventArgs e)
if (e.Button == MouseButtons.Left && !Program.Settings.ActionsToolbarLockPosition)
{
NativeMethods.ReleaseCapture();
- NativeMethods.DefWindowProc(Handle, (uint)WindowsMessages.SYSCOMMAND, (UIntPtr)NativeConstants.MOUSE_MOVE, IntPtr.Zero);
+ var m = Message.Create(Handle, (int)WindowsMessages.SYSCOMMAND, new IntPtr(NativeConstants.MOUSE_MOVE), IntPtr.Zero);
+ DefWndProc(ref m);
}
}
diff --git a/ShareX/Forms/MainForm.cs b/ShareX/Forms/MainForm.cs
index 82409b764..6af24c66f 100644
--- a/ShareX/Forms/MainForm.cs
+++ b/ShareX/Forms/MainForm.cs
@@ -298,6 +298,36 @@ public void UpdateControls()
IsReady = true;
}
+ protected override void WndProc(ref Message m)
+ {
+ if (m.Msg == (int)WindowsMessages.QUERYENDSESSION)
+ {
+ var reason = (EndSessionReasons)m.GetLParam(typeof(EndSessionReasons));
+ if (reason.HasFlag(EndSessionReasons.ENDSESSION_CLOSEAPP))
+ {
+ // Register for restart. This allows our application to automatically restart when it is installing an update from the Store.
+ // Also allows it to restart if it gets terminated for other reasons (see description of ENDSESSION_CLOSEAPP).
+ // Add the silent switch to avoid ShareX popping up in front of the user when the application restarts.
+ NativeMethods.RegisterApplicationRestart("-silent", 0);
+ }
+ m.Result = new IntPtr(1); // "Applications should respect the user's intentions and return TRUE."
+ }
+ else if (m.Msg == (int)WindowsMessages.ENDSESSION)
+ {
+ if (m.WParam != IntPtr.Zero)
+ {
+ // If wParam is not equal to false (0), the application can be terminated at any moment after processing this message
+ // thus should save its data while processing the message.
+ SettingManager.SaveAllSettings();
+ }
+ m.Result = IntPtr.Zero; // "If an application processes this message, it should return zero."
+ }
+ else
+ {
+ base.WndProc(ref m);
+ }
+ }
+
private void AfterShownJobs()
{
if (!Program.Settings.ShowMostRecentTaskFirst && lvUploads.Items.Count > 0)