0

VS6とATLをCServiceModuleとともに使用して、カスタムWindowsサービスを実装しています。致命的なエラーが発生した場合、サービスは自動的にシャットダウンする必要があります。CServiceModuleはすべてのファイルの_Module変数を介して利用できるので、CServiceModule :: Runがメッセージのポンピングを停止し、それ自体をシャットダウンするように、このようなことを考えました。

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

これは正しいですか、それともあなたはより良い考えを持っていますか?

4

3 に答える 3

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;
} 
于 2009-01-21T00:35:22.043 に答える
0

これを行うと、サービス マネージャーはサービスがクラッシュしたと見なし、ユーザーがサービスを自動再起動するように設定した場合は、サービスがクラッシュすると思います。

.NET では、ServiceController を使用して、サービスをシャットダウンするように通知します。.NET のこのようなもののほとんどは単なるラッパーであるため、Win32 でも似ていると思います。申し訳ありませんが、サービスをシャットダウンするための 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;
        }
     }
  }
于 2008-12-05T14:58:51.937 に答える
0

サービスをシャットダウンするには、おそらく ControlService またはControlServiceExメソッドを使用する必要があります。CServiceModule から必要なハンドルを取得できるはずです。

于 2008-12-07T16:47:54.197 に答える