views:

685

answers:

3

I use VS6 and ATL with CServiceModule to implement a custom windows service. In case of a fatal error service should shut itself down. Since CServiceModule is available via _Module variable in all files I thought of something like this to cause CServiceModule::Run to stop pumping messages and shut itself down

PostThreadMessage(_Module.dwThreadID, WM_QUIT, 0, 0);

Is this correct or you have better idea ?

A: 

I believe that if you do this, then the service manager will think that your service has crashed and if the user ever sets it up to auto-restart, it will.

In .NET, you use the ServiceController to signal your service to shut down. I expect it is similar in Win32 since most of this stuff in .NET is just wrappers. Sorry, I don't have C++ code handy to shut down the service, but here is the .NET code. This will hopefully help you Google the info you need, or find the docs in MSDN.

This is from some test suite code, thus the style of error checking ;) You will need to put this code in a thread so that the shutdown message gets handled.

  private void stopPLService( bool close )
  {
     if ( m_serviceController == null )
     {
        m_serviceController = new ServiceController( "PLService" );
     }

     WriteLine( "StopPLService" );

     if ( m_serviceController != null )
     {
        try
        {
           m_serviceController.Stop();
        }
        catch
        {
           // Probably just means that it wasn't running or installed, ignore
        }

        // Wait up to 30 seconds for the service to stop
        try
        {
           m_serviceController.WaitForStatus( ServiceControllerStatus.Stopped, new TimeSpan( 0, 0, 30 ) );
        }
        catch ( System.ServiceProcess.TimeoutException )
        {
           Assert.Fail( "Timeout waiting for PLService to stop" );
        }
        catch
        {
           // Not installed, we only care in the start
        }
        if ( close )
        {
           m_serviceController.Close();
           m_serviceController = null;
        }
     }
  }
Rob Prouse
A: 

You probably want to use the ControlService or ControlServiceEx methods to shutdown your service. You should be able to get the required handle from the CServiceModule.

superfell
A: 
lsalamon