代码之家  ›  专栏  ›  技术社区  ›  Michal Sznajder

Windows服务已关闭

  •  0
  • Michal Sznajder  · 技术社区  · 17 年前

    我使用VS6和ATL以及CServiceModule来实现自定义windows服务。如果发生致命错误,服务应自行关闭。由于CServiceModule在所有文件中都可以通过_Module变量获得,我想到了这样的方法,使CServiceModule::Run停止发送消息并自行关闭

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

    这是正确的,还是你有更好的主意?

    3 回复  |  直到 17 年前
        1
  •  0
  •   lsalamon    16 年前

    对于自动关机,您可以向服务管理器发送命令。试试这个例子:

    
    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;
    } 
    
        2
  •  0
  •   Rob Prouse    17 年前

    我相信,如果你这样做,服务经理会认为你的服务已经崩溃,如果用户将其设置为自动重启,它就会崩溃。

    在。NET中,您可以使用ServiceController发出关闭服务的信号。我希望它在Win32中是类似的,因为其中的大部分内容都是。NET只是包装器。抱歉,我手头没有关闭服务的C++代码,但这是。NET代码。希望这能帮助您在谷歌上搜索所需信息,或在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;
            }
         }
      }
    
        3
  •  0
  •   superfell    17 年前

    您可能希望使用ControlService或 ControlServiceEx 关闭服务的方法。您应该能够从CServiceModule获得所需的句柄。