サービス プログラムのメイン関数の作成

サービス プログラムメイン関数は、StartServiceCtrlDispatcher 関数を呼び出してサービス コントロール マネージャー (SCM) に接続し、コントロール ディスパッチャー スレッドを開始します。 ディスパッチャー スレッドはループし、ディスパッチ テーブルで指定されたサービスに対する受信制御要求を待機します。 このスレッドは、エラーが発生したとき、またはプロセス内のすべてのサービスが終了したときにを返します。 プロセス内のすべてのサービスが終了すると、SCM は制御要求をディスパッチャー スレッドに送信して終了するように指示します。 その後、このスレッドは StartServiceCtrlDispatcher 呼び出しから戻り、プロセスを終了できます。

このサンプルでは、次のグローバル定義を使用します。

#define SVCNAME TEXT("SvcName")

SERVICE_STATUS          gSvcStatus; 
SERVICE_STATUS_HANDLE   gSvcStatusHandle; 
HANDLE                  ghSvcStopEvent = NULL;

次の例は、1 つのサービスをサポートするサービス プログラムのエントリ ポイントとして使用できます。 サービス プログラムが複数のサービスをサポートしている場合は、ディスパッチ ャー スレッドで監視できるように、追加のサービスの名前をディスパッチ テーブルに追加します。

_tmain関数はエントリ ポイントです。 SvcReportEvent 関数は、情報メッセージとエラーをイベント ログに書き込みます。 SvcMain 関数の記述の詳細については、「 ServiceMain 関数の記述」を参照してください。 SvcInstall 関数の詳細については、「 サービスのインストール」を参照してください。 SvcCtrlHandler 関数の記述の詳細については、「 コントロール ハンドラー関数の記述」を参照してください。 SvcReportEvent 関数のソースを含む完全なサンプル サービスについては、「 Svc.cpp」を参照してください。

//
// Purpose: 
//   Entry point for the process
//
// Parameters:
//   None
// 
// Return value:
//   None, defaults to 0 (zero)
//
int __cdecl _tmain(int argc, TCHAR *argv[])
{ 
    // If command-line parameter is "install", install the service. 
    // Otherwise, the service is probably being started by the SCM.

    if( lstrcmpi( argv[1], TEXT("install")) == 0 )
    {
        SvcInstall();
        return;
    }

    // TO_DO: Add any additional services for the process to this table.
    SERVICE_TABLE_ENTRY DispatchTable[] = 
    { 
        { SVCNAME, (LPSERVICE_MAIN_FUNCTION) SvcMain }, 
        { NULL, NULL } 
    }; 
 
    // This call returns when the service has stopped. 
    // The process should simply terminate when the call returns.

    if (!StartServiceCtrlDispatcher( DispatchTable )) 
    { 
        SvcReportEvent(TEXT("StartServiceCtrlDispatcher")); 
    } 
} 

メッセージ コンパイラによって生成される Sample.h の例を次に示します。 詳細については、「 Sample.mc」を参照してください。

 // The following are message definitions.
//
//  Values are 32 bit values layed out as follows:
//
//   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
//   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
//  +---+-+-+-----------------------+-------------------------------+
//  |Sev|C|R|     Facility          |               Code            |
//  +---+-+-+-----------------------+-------------------------------+
//
//  where
//
//      Sev - is the severity code
//
//          00 - Success
//          01 - Informational
//          10 - Warning
//          11 - Error
//
//      C - is the Customer code flag
//
//      R - is a reserved bit
//
//      Facility - is the facility code
//
//      Code - is the facility's status code
//
//
// Define the facility codes
//
#define FACILITY_SYSTEM                  0x0
#define FACILITY_STUBS                   0x3
#define FACILITY_RUNTIME                 0x2
#define FACILITY_IO_ERROR_CODE           0x4


//
// Define the severity codes
//
#define STATUS_SEVERITY_WARNING          0x2
#define STATUS_SEVERITY_SUCCESS          0x0
#define STATUS_SEVERITY_INFORMATIONAL    0x1
#define STATUS_SEVERITY_ERROR            0x3


//
// MessageId: SVC_ERROR
//
// MessageText:
//
//  An error has occurred (%2).
//  
//
#define SVC_ERROR                        ((DWORD)0xC0020001L)

サービス エントリ ポイント

完全なサービス サンプル