I'm using the following c # code to temporarily block the shutdown of a WinForm application without success, what I observe is that the System doesn't shutdown at all, probably because the work I have to do when receiving the shutdown notification is being made on the UI thread. Windows does not terminate the application if the application is unresponsive after 30 secs as documented. See the attached image.enter image description here
public Form1()
{
InitializeComponent();
// Define the priority of the application (0x3FF = The higher priority)
SetProcessShutdownParameters(0x3FF, SHUTDOWN_NORETRY);
}
[DllImport("user32.dll")]
public extern static bool ShutdownBlockReasonCreate(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)] string pwszReason);
[DllImport("user32.dll")]
public extern static bool ShutdownBlockReasonDestroy(IntPtr hWnd);
[DllImport("kernel32.dll")]
static extern bool SetProcessShutdownParameters(uint dwLevel, uint dwFlags);
private static int WM_QUERYENDSESSION = 0x11;
private static int WM_ENDSESSION = 0x16;
public const uint SHUTDOWN_NORETRY = 0x00000001;
private ManualResetEvent rEvent = new ManualResetEvent(false);
private bool blocked = false;
protected override void WndProc(ref System.Windows.Forms.Message m)
{
if (m.Msg == WM_QUERYENDSESSION)
{
if (!blocked)
{
blocked = true;
ShutdownBlockReasonCreate(this.Handle, "Closing in progress");
this.BeginInvoke((Action)(() =>
{
// My clean-up work on UI thread
Thread.Sleep(600000);
// Allow Windows to shutdown
ShutdownBlockReasonDestroy(this.Handle);
}));
m.Result = IntPtr.Zero;
}
else
{
m.Result = (IntPtr)1;
}
}
if (m.Msg == WM_ENDSESSION)
{
if (blocked)
{
ShutdownBlockReasonDestroy(this.Handle);
m.Result = (IntPtr)1;
}
}
// If this is WM_QUERYENDSESSION, the closing event should be
// raised in the base WndProc.
base.WndProc(ref m);
} //WndProc