Add support for QUERYENDSESSION message and the Restart Manager

This commit is contained in:
Charles Milette 2018-10-13 12:18:10 -04:00
parent a210bf5c2a
commit e74f99aaab
No known key found for this signature in database
GPG key ID: 1A5AE81377AD973A
4 changed files with 73 additions and 1 deletions

View file

@ -3131,4 +3131,42 @@ public enum CreateProcessFlags : uint
PROFILE_SERVER = 0x40000000,
CREATE_IGNORE_SYSTEM_DEFAULT = 0x80000000,
}
[Flags]
public enum RegisterApplicationRestartFlags : uint
{
/// <summary>
/// Do not restart the process if it terminates due to an unhandled exception.
/// </summary>
RESTART_NO_CRASH = 1,
/// <summary>
/// Do not restart the process if it terminates due to the application not responding.
/// </summary>
RESTART_NO_HANG = 2,
/// <summary>
/// Do not restart the process if it terminates due to the installation of an update.
/// </summary>
RESTART_NO_PATCH = 4,
/// <summary>
/// Do not restart the process if the computer is restarted as the result of an update.
/// </summary>
RESTART_NO_REBOOT = 8
}
[Flags]
public enum EndSessionReasons : uint
{
/// <summary>
/// The application is using a file that must be replaced, the system is being serviced, or system resources are exhausted.
/// </summary>
ENDSESSION_CLOSEAPP = 0x1,
/// <summary>
/// The application is forced to shut down.
/// </summary>
ENDSESSION_CRITICAL = 0x40000000,
/// <summary>
/// The user is logging off.
/// </summary>
ENDSESSION_LOGOFF = 0x80000000
}
}

View file

@ -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

View file

@ -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);
}
}

View file

@ -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)