Search code examples
windowswindows-servicesshutdown

Windows will not shutdown programmatically when logged off


I have an application that is launched from within a service using a local administrator account. This application is accessible by a web browser and the host PC can be shut down through this interface.

If a user is logged into the host PC and I browse to it and shut it down, the application exits and shuts down the PC as I would expect - using ExitWindowsEx() (with the shutdown priviledge enabled).

If, however, the PC is logged off, I browse to it - the application still running within the service, and attempt a shutdown using ExitWindowsEx(), it returns successful and the appears to be no problem but the PC never shuts down.

I have also tried InitiateSystemShutdown() which bizzarely fails and returns error 2! (The system cannot find the file specified).

It doesn't seem to matter what account I use to launch the application with.

Any help would be greatly appreciated!

Thanks.


Solution

  • Sadly, cannot repro. I have a pre-existing service which exposes a mailslot, so I added the code:

    void RebootThisMachine ()
    {
       if (GrabPrivilege (SE_SHUTDOWN_NAME))
       {
          if (!InitiateSystemShutdown (NULL,NULL,0,TRUE,TRUE))
          {
             wsprintf (g_szDebug, TEXT("RebootMachine - ISS failed, error %d"),
                       GetLastError()) ;
             DebugMessage (DEBUG_ERROR, g_szDebug) ;
          }
       }
       else
       {
          wsprintf (g_szDebug, TEXT("RebootMachine - cannot grab priv, error %d"),
                    GetLastError()) ;
          DebugMessage (DEBUG_ERROR, g_szDebug) ;
       }
    }
    

    and called it when I received a mailslot message from a little command-line utility I wrote. InitiateSystemShutdown is the right API for a service, and this reboots the machine running the service whether it's logged in or not. The shutdown does take a while if my (vista) machine is not logged in, but it eventually works (after 30-40s of saying "shutting down"). My service executes under LocalSystem. GrabPrivilege is the same code as I posted before.

    So you can take heart from the fact that what you're trying to do is possible. I see you are using an administrator account to run your service. Have you tried running your service under LocalSystem for the purposes of a shutdown test? Perhaps the privs of your administrator don't quite match those of LocalSystem...