According to the documentation, to disable the shutdown, you need to return FALSE in response to WM_QUERYENDSESSION .
What else, you should not work in this message handler. Work must take place elsewhere. If you do not reply to this message in a timely manner, the system will not wait for you.
- Call
ShutdownBlockReasonCreate before you get started. - At run time, return
FALSE from WM_QUERYENDSESSION . Do not work with this message. Come back immediately. - When you are done, call
ShutdownBlockReasonDestroy .
The handler for WM_QUERYENDSESSION might look like this:
procedure TMainForm.WMQueryEndSession(var Msg: TWMQueryEndSession); begin if Working then Msg.Result := 0 else inherited; end;
And then the code that does the work should call ShutdownBlockReasonCreate before it starts, ShutdownBlockReasonDestroy when the job is done, and make sure that the Working property above is evaluated as True at run time.
If your work blocks the main thread, you are having problems. The main thread must respond, otherwise the system will not wait for you. Putting work on stream is often a way forward. If your main window does not appear, you cannot block the shutdown. Details are explained here: http://msdn.microsoft.com/en-us/library/ms700677.aspx
If you get to sending WM_ENDSESSION , then it's too late. The system goes down that it can.
To test this, I just send him the "final task" through the task manager.
This has nothing to do with shutdown lock. The way you check the shutdown lock is to log out. If the user insists on killing your process, little can be done. Sertac's answer details this.
Finally, ignoring the return values ββof API calls is also very bad. Do not do that.
source share