How to pause Windows shutdown
delphi, delphi-5, system-shutdown
Solution
Since Windows Vista, if you register a shutdown reason string with the OS or if your application has a top level window, the OS will wait indefinitely for your program to return from `WM_QUERYENDSESSION` while displaying the blocking applications screen - or until the user chooses to forcefully end the program of course.
The below sample code simulates a 45 seconds wait with `Sleep`. In the first five seconds of the wait the OS waits patiently, only then it displays the full screen UI. The only way to show the screen immediately is to immediately return false from `WM_QUERYENDSESSION`. But in this case you won't be able to resume shutdown.
For details on shutdown behavior of the OS for Vista and later, see documentation.
type
TForm1 = class(TForm)
..
protected
procedure WMQueryEndSession(var Message: TWMQueryEndSession);
message WM_QUERYENDSESSION;
..
...
function ShutdownBlockReasonCreate(hWnd: HWND; Reason: LPCWSTR): Bool;
stdcall; external user32;
function ShutdownBlockReasonDestroy(hWnd: HWND): Bool; stdcall; external user32;
procedure TForm1.WMQueryEndSession(var Message: TWMQueryEndSession);
const
ENDSESSION_CRITICAL = $40000000;
begin
Message.Result := LRESULT(True);
if ((Message.Unused and ENDSESSION_CRITICAL) = 0) then begin
ShutdownBlockReasonCreate(Handle, 'please wait while muting...');
Sleep(45000); // do your work here
ShutdownBlockReasonDestroy(Handle);
end;
end;
Problem
I need to mute/un-mute the sound card at startup and shutdown. I have found some code to do the work, but often Windows slams through the shutdown and the sound never gets muted. Can someone please tell me how to pause the shutdown long enough for my app to mute the sound? I can use a simple TTimer to pause the app long enough for it to run the muting and then let Windows get on with shutting down. How do I tell Windows to wait though? I notice that if I leave Firefox running and try to shutdown, Windows stops with a message, "These programs are preventing windows closing..." and needs a click to force Firefox to close. I need to find that.