title: How to correctly use SetServiceStatus to tell Windows my service is stopping?
body: <p>Sorry about the length of the sample, but in order to get all the required components of a service it has to be this long.</p>
  
  <p>Using the help of others here I've managed to get a service that starts cleanly, but now it won't stop cleanly.</p>
  
  <p>On the first attempt to stop it quickly gives the error</p>
  
  <pre><code>Could not stop the My service service on local computer
  The service did not return an error. This could be an internal Windows error or an internal service error
  If the problem persists, contact your system administrator
  </code></pre>
  
  <p>and the service continues to run, even after the 5 minutes that the sleep loop takes.</p>
  
  <p>On the second attempt to stop, task manager shows the process stops immediately, but the Service Manager takes a very long time to give the error</p>
  
  <pre><code>Could not stop the My service service on local computer
  Error 1053: The service did not respond to the start or control request in a timely fashion.
  </code></pre>
  
  <p>And here is the source code</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;sys/stat.h&gt;
  #include &lt;fcntl.h&gt;
  #include &lt;string.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;windows.h&gt;
  #include &lt;winsvc.h&gt;
  #include &lt;time.h&gt;
  
  #define MY_SVC_NAME "My service"
  #define THE_PROG "\"C:\\Program Files\\My software\\bin\\The Prog.exe\""
  #define SLEEP_TIME 300000
  
  SERVICE_STATUS ServiceStatus;
  SERVICE_STATUS_HANDLE hStatus;
  
  void WINAPI ServiceMain(DWORD argc, LPSTR argv);
  void WINAPI ControlHandler(DWORD request);
  void InitService();
  
  
  int cont_running = 1;
  
  DWORD WINAPI ServiceHandlerProc(DWORD ControlCode, DWORD a, void *b, void *c)
  {
    switch (ControlCode) {
    case SERVICE_CONTROL_STOP :
      cont_running = 0;
      ServiceStatus.dwCheckPoint=0;
      ServiceStatus.dwWin32ExitCode = 0;
      ServiceStatus.dwCurrentState  = SERVICE_STOP_PENDING;
      ServiceStatus.dwWaitHint =2000;
      SetServiceStatus (hStatus, &amp;ServiceStatus);
      Sleep(1000);
      ServiceStatus.dwCurrentState  = SERVICE_STOPPED;
      SetServiceStatus (hStatus, &amp;ServiceStatus);
      break;
    case SERVICE_CONTROL_SHUTDOWN :
      cont_running = 0;
      ServiceStatus.dwCheckPoint=0;
      ServiceStatus.dwWin32ExitCode = 0;
      ServiceStatus.dwCurrentState  = SERVICE_STOP_PENDING;
      ServiceStatus.dwWaitHint =2000;
      SetServiceStatus (hStatus, &amp;ServiceStatus);
      Sleep(1000);
      ServiceStatus.dwCurrentState  = SERVICE_STOPPED;
      SetServiceStatus (hStatus, &amp;ServiceStatus);
      break;
    }
  
    return 0;
  
  }
  
  void WINAPI ServiceMain(DWORD argc, LPSTR argv)
  {
    int hServiceStatus;
  
    ServiceStatus.dwServiceType        = SERVICE_WIN32;
    ServiceStatus.dwCurrentState       = SERVICE_START_PENDING;
    ServiceStatus.dwControlsAccepted   = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
    ServiceStatus.dwWin32ExitCode      = 0;
    ServiceStatus.dwServiceSpecificExitCode = 0;
    ServiceStatus.dwCheckPoint         = 0;
    ServiceStatus.dwWaitHint           = 0;
  
    hServiceStatus = RegisterServiceCtrlHandlerEx(MY_SVC_NAME, ServiceHandlerProc,0);
    /*
    if (hStatus == (SERVICE_STATUS_HANDLE)0) {
      return;
    }
    */
  
    Sleep(1000);
  
    ServiceStatus.dwCheckPoint=0;
    ServiceStatus.dwWaitHint=0;
    ServiceStatus.dwCurrentState=SERVICE_RUNNING;
    SetServiceStatus( hServiceStatus, &amp;ServiceStatus);
  
    InitService();
  
    return;
  }
  
  void InitService()
  {
    cont_running=1;
    do {
      system(THE_PROG);
      Sleep(SLEEP_TIME);
    } while (cont_running);
  }
  
  int main(int argc, char *argv[], char *envp[])
  {
    SERVICE_TABLE_ENTRY ServiceStartTable[2];
    ServiceStartTable[0].lpServiceName = MY_SVC_NAME;
    ServiceStartTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
    ServiceStartTable[1].lpServiceName = NULL;
    ServiceStartTable[1].lpServiceProc = NULL;
  
  
    if (!StartServiceCtrlDispatcher(ServiceStartTable))
    {
      DWORD err = GetLastError();
      if (err == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)
        return 1;
    }
  
    return 0;
  }
  </code></pre>
  
  <p>I've referred to the following documents without success
  <a href="http://msdn.microsoft.com/en-us/library/ms809975.aspx" rel="nofollow">http://msdn.microsoft.com/en-us/library/ms809975.aspx</a>
  LUA Service Reference Manual</p>