none
Design Windows Service not to allow the sysem shutdown RRS feed

  • Question

  • We are building an IT infrastructure management system. Our agent software allows system administrators to perform remote task efficiently. However, we would like our agent (that works as a windows service on the target computer) not to allow the system shutdown, in case we set it remotely to do so. This way we could perform the routine maintanance tasks after the office hours are over, and then shut down the PC's by ourselves remotely. Is there a way to get the Windows Service to cancel the system shutdown when it recieves WM_TERMINATE or something? Thank you.
    Max Pavlov http://maxpavlov.com
    Wednesday, May 20, 2009 7:47 AM

Answers

  • Actually you can.

    1. I impersonated the small windows app that is started by my service to be ran under the currently logged on user's credentials.
    2. I have made the main form of this application invisible, but the window class was still recieveing message to it's window procedure.
    3. When a window has recieved an WM_QUERYENDSESSION I send Zero as a result. In Windows, if any application responds with a 0 to a WM_QUERYENDSESSION even, the log-off/shutdown event is being canceled.

    protected override void WndProc(ref Message m)
            {
                if (m.Msg == WM_QUERYENDSESSION)
                {
                    m.Result = IntPtr.Zero;
                    return;
                }
                base.WndProc(ref m);
            }

    Above is the example of code, how one could "watch" for shutdown/log-off even and process in as needed by the logic.


    Max Pavlov http://maxpavlov.com
    • Marked as answer by Max Pavlov Friday, May 29, 2009 4:15 PM
    Friday, May 29, 2009 4:15 PM

All replies

  • System shutdown is controlled by user. And application has no chance to prevent it, only appropriately react to prevent data corruption.
    Vitaliy Liptchinsky http://dotnetframeworkplanet.blogspot.com/
    Wednesday, May 20, 2009 8:21 AM
  • As Vitaliy said above, that's not possible.

    However, I guess you can play with enabling/disabling the Shutdown button in Start Menu:

    HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer and Value name is "NoClose", 1 is to disable, 0 is to enable.

    • Marked as answer by Max Pavlov Wednesday, May 20, 2009 7:04 PM
    • Unmarked as answer by Max Pavlov Friday, May 29, 2009 1:31 PM
    • Marked as answer by Max Pavlov Friday, May 29, 2009 1:31 PM
    • Unmarked as answer by Max Pavlov Friday, May 29, 2009 1:31 PM
    • Unmarked as answer by Max Pavlov Friday, May 29, 2009 1:31 PM
    • Unmarked as answer by Max Pavlov Friday, May 29, 2009 1:31 PM
    Wednesday, May 20, 2009 10:40 AM
  • Yup.  This calls for a low-tech solution: a lock on a door.

    Hans Passant.
    Wednesday, May 20, 2009 10:41 AM
    Moderator
  • Thanks! Is there, by any chance, a way to put my own button to the start menu, so my application is being executed, instead of the actual shutdown event?
    Max Pavlov http://maxpavlov.com
    Wednesday, May 20, 2009 7:05 PM
  • Noticed you had unmarked the answer - has anything changed with your problem?




    http://codevanced.net
    Friday, May 29, 2009 1:55 PM
  • Actually you can.

    1. I impersonated the small windows app that is started by my service to be ran under the currently logged on user's credentials.
    2. I have made the main form of this application invisible, but the window class was still recieveing message to it's window procedure.
    3. When a window has recieved an WM_QUERYENDSESSION I send Zero as a result. In Windows, if any application responds with a 0 to a WM_QUERYENDSESSION even, the log-off/shutdown event is being canceled.

    protected override void WndProc(ref Message m)
            {
                if (m.Msg == WM_QUERYENDSESSION)
                {
                    m.Result = IntPtr.Zero;
                    return;
                }
                base.WndProc(ref m);
            }

    Above is the example of code, how one could "watch" for shutdown/log-off even and process in as needed by the logic.


    Max Pavlov http://maxpavlov.com
    • Marked as answer by Max Pavlov Friday, May 29, 2009 4:15 PM
    Friday, May 29, 2009 4:15 PM
  • I realize this is a super-old thread, but there doesn't seem to be an answer, and the OP's post ranked pretty high in a Google search, so I'm gonna throw in my two cents.

    1. I impersonated the small windows app that is started by my service to be ran under the currently logged on user's credentials.
    2. I have made the main form of this application invisible, but the window class was still recieveing message to it's window procedure.
    3. When a window has recieved an WM_QUERYENDSESSION I send Zero as a result. In Windows, if any application responds with a 0 to a WM_QUERYENDSESSION even, the log-off/shutdown event is being canceled.

    Acutally, in my tests (just with a Win32 application with an invisible top-level window, mind you, not a service) I get the WM_QUERYENDSESSION message, but even if I return 0 (e.g. set m.Result = IntPtr.Zero) the workstation seems to shutdown/restart/logoff anyway. Sometimes I will get a subsequent WM_ENDSESSION message with wParam = 0 (indicating the session is not ending), but the shutdown happens regardless.

    Anyhow, MSDN says you shouldn't do that anyway. A better approach would be to adjust the user rights assignments to control who can shutdown a system. And remember: if someone has physical access to a given computer, and they want to shutdown this computer but there's no such option (or you block it) 99 times out of a 100 they'll just pull the power cable.

    So, in my mind it comes down to a question of do I want users to shutdown gracefully, or just pull power?

    Saturday, August 11, 2012 1:21 AM