How to detect Windows shutdown or logoff

59,280

Solution 1

Attach an event handler method to the SystemEvents.SessionEnding event, and your handler method will be called each time the event is raised. Handling this event will allow you to cancel the pending log off or shut down, if you wish. (Although that doesn't actually work like it sounds in current operating systems; for more information see the MSDN documentation here.)

If you don't want to cancel the event, but just react to it appropriately, you should handle the SystemEvents.SessionEnded event instead.

You must make sure that you detach your event handlers when the application is closed, however, because both of these are static events.

Solution 2

You can use a native solution via pinvoke if your code is not running in a non-interactive session (such as a system service):

//SM_SHUTTINGDOWN = 0x2000
bool bShutDownPending = GetSystemMetrics(SM_SHUTTINGDOWN) != 0;
Share:
59,280
Andrea Nagar
Author by

Andrea Nagar

Updated on July 09, 2022

Comments

  • Andrea Nagar
    Andrea Nagar almost 2 years

    I need to detect when Windows is shutdown (or restarted) or when the user is logging off. I need to properly close the application before the application is closed. I noticed that no exit application event is raised when Windows is closing day.

    I read the post Is there a way in c# to detect a Windows shutdown/logoff and cancel that action (after asking the user)

    but I'm not sure of where I should perform the operations before closing. Thanks.

  • Ultratrunks
    Ultratrunks over 11 years
    This thread is probably dead now, but what happens if your application starts AFTER shutdown has already started. Will both of those events still work since technically you missed it already. This is the kind of problem I'm having now. My application is designed to stay running, and on shutdown it tries to restart after its been killed by windows in preparation for shutting down.
  • Cody Gray
    Cody Gray about 11 years
    @Ultratrunks You're fighting a losing battle here. An application cannot reliably prevent system shutdown, all it can do is react to it.
  • Ultratrunks
    Ultratrunks about 11 years
    @CodyGray Per my comment, I'm not looking for anything that prevents shutting down. I just want to know about it. Actually, I'm inadvertently preventing shutdown right now because my application tries to start after the shutdown process has started, and it immediately crashes and leaves a window up on the screen that prevents shutdown from occurring. Its a nuisance so i want to be able to query the system and ask "are you in the middle of shutting down?" so I can act accordingly.
  • Gusdor
    Gusdor over 10 years
    Can you elaborate on why you need to unattach the event? Your application is closing. Nothing managed will leak. Will unmanaged memory to kept open?
  • harry
    harry about 9 years
    Keeping in mind, of course, that this is a polling solution - no callback, no event handling - you have to check until this condition is satisfied.
  • JobaDiniz
    JobaDiniz about 8 years
    Is there a way to test these events without actually turn off or logoff?
  • underfilho
    underfilho over 6 years
    how to use it in C#? I only find in C++
  • c00000fd
    c00000fd over 6 years
    @MahmoudAl-Qudsi: Sure. It just adds a little bit more work. Simply create a worker thread that polls in a loop for that value and sets a locked global boolean variable with the result, or invokes your custom event handler. The important part is to ensure that it doesn't "eat up" too many CPU cycles. For that simply put a Sleep(10); call in each cycle. Additionally you may implement a stop event to be able to exit that thread.
  • harry
    harry over 6 years
    Since there's an asynchronous event-driven solution, you shouldn't need to waste system resources with a separate thread and a CPU loop.
  • c00000fd
    c00000fd over 6 years
    @MahmoudAl-Qudsi: did you see my explanation? If implemented as I suggested there's no "waste of system resources" that can be significant for any measure, esp. for a .NET application. It's been a while and I can't find my exact application, but the reason I offered the workaround above is for the situation when .NET's SystemEvents.SessionEnded was not available. Otherwise obviously use it. Additionally you might want to know if the user is logging off right-at-that-moment, say, when implementing another event. In that case this solution is more robust and no polling is needed at all.
  • sɐunıɔןɐqɐp
    sɐunıɔןɐqɐp about 4 years
    @JobaDiniz: You could try posting an event directly to the application. You could even do this from another application. I did not try it for this specific event yet. See: stackoverflow.com/a/1497965/823321