2008-12-05 4 views
0

Я использую VS6 и ATL с CServiceModule для реализации пользовательской службы Windows. В случае фатальной ошибки служба должна закрыться. Так CServiceModule доступно через переменную _Module во всех файлах я думал что-то вроде этого, чтобы вызвать CServiceModule :: Run, чтобы остановить насосные сообщения и отключилсяСлужба Windows отключена

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

правильно ли это или у вас есть идея получше?

ответ

0

Для самостоятельного отключения вы отправляете команду Service Manager. Попробуйте этот образец:


BOOL StopServiceCmd (const char * szServiceName) 
{ 
    SC_HANDLE schService; 
    SC_HANDLE schSCManager; 
    SERVICE_STATUS ssStatus;  // current status of the service 
    BOOL bRet; 
    int iCont=0; 

    schSCManager = OpenSCManager( 
     NULL, // machine (NULL == local) 
     NULL, // database (NULL == default) 
     SC_MANAGER_ALL_ACCESS // access required 
     ); 
    if (schSCManager) 
    { 
     schService = OpenService(schSCManager, szServiceName, SERVICE_ALL_ACCESS); 

     if (schService) 
     { 
      // try to stop the service 
      if (ControlService(schService, SERVICE_CONTROL_STOP, &ssStatus)) 
      { 
       Sleep(1000); 

       while(QueryServiceStatus(schService, &ssStatus)) 
       { 
        iCont++; 
        if (ssStatus.dwCurrentState == SERVICE_STOP_PENDING) 
        { 
         Sleep(1000); 
         if (iCont > 4) break; 
        } 
        else 
         break; 
       } 

       if (ssStatus.dwCurrentState == SERVICE_STOPPED) 
        bRet = TRUE; 
       else 
        bRet = FALSE; 
      } 

      CloseServiceHandle(schService); 
     } 
     else 
      bRet = FALSE; 

     CloseServiceHandle(schSCManager); 
    } 
    else 
     bRet = FALSE; 

    return bRet; 
} 
0

Я считаю, что если вы это сделаете, менеджер службы подумает, что ваш сервис разбился, и если пользователь когда-либо настраивает его на автоматический перезапуск, он будет.

В .NET вы используете ServiceController, чтобы сигнализировать о завершении службы. Я ожидаю, что это похоже на Win32, поскольку большая часть этого материала в .NET - это просто обертки. К сожалению, у меня нет кода на C++, который можно отключить, но вот код .NET. Это, мы надеемся, поможет вам Google в информации, которая вам нужна, или найти документы в MSDN.

Это из некоторого кода тестового набора, таким образом, стиль проверки ошибок;) Вам нужно будет поместить этот код в поток, чтобы обработать сообщение о завершении работы.

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; 
     } 
    } 
    } 
0

Вы, вероятно, хотите использовать ControlService или ControlServiceEx методы для выключения службы. Вы должны иметь возможность получить требуемый дескриптор из модуля CServiceModule.