Skip to main content.

Friday, September 22, 2006

Windowsサービスプログラム(その2)VC++クラス実装版

Windowsサービスプログラムのサンプルです。以前の「Windowsサービスプログラム」で作成したサービスプログラムと動きは同じですが、今回はVC++のクラスとして実装しました。サービスプログラム関連のAPIをクラスのメンバ関数から呼び出しています。サービスプログラムの実際の処理となる部分をC++のクラスとして設計、実装した場合は、サービスの部分もこのようにクラスにした方が全体として一貫性があっていいかと思います。

ヘッダファイルでのクラス定義は以下になります。

class CWinService
{
public:
    CWinService();
    virtual ~CWinService();

    //インストールとアンインストール
    BOOL Install();
    BOOL Remove();

    //実行
    void Run();
private:
    SERVICE_STATUS serviceStatus;
    SERVICE_STATUS_HANDLE serviceStatusHandle;

    //サービスメインとSCMハンドラの実処理
    void WINAPI ServiceCtrlHandler(DWORD);
    void WINAPI ServiceMain(DWORD,LPTSTR*);

    //APIをコールする際にはstatic関数でないとコールできないので以下を用意
    static void WINAPI _ServiceCtrlHandler(DWORD);
    static void WINAPI _ServiceMain(DWORD, LPTSTR*);

    static CWinService* lpCWinService;

    //サービス名称保持
    char serviceName[BUFSIZ];
    char serviceDisplayName[BUFSIZ];
    char serviceExeName[BUFSIZ];

    //終了イベント
    HANDLE hServerStopEvent;
};

ポイントはstatic関数とstatic変数の部分になるかと思います。これは、static関数でないとAPIに渡せないので(コンパイルエラーになります。)static関数を定義して、その関数をAPIに渡しています。またそのstatic関数の中で、static変数で定義したポインタにthisポインタを設定して、thisポインタから実際の処理の関数を呼び出しています。以下がその一部分です。プログラム全体は、お手数ですがファイルをダウンロードしてご覧下さい。

//
// 実行
//
void CWinService::Run()
{
SERVICE_TABLE_ENTRY DispatchTable[]={{serviceName,_ServiceMain},{NULL,NULL}};
StartServiceCtrlDispatcher(DispatchTable);
}

//
// サービスのメイン(呼び出し用)
//
void WINAPI CWinService::_ServiceMain(DWORD argc, LPTSTR *argv)
{
lpCWinService->ServiceMain(argc,argv);
}

クラスの使い方は、以下のようになります。

//宣言、初期化
CWinService winService;

//インストール時
winService.Install();

//アンインストール時
winService.Remove();

//実行時
winService.Run();

使い方は前回と同じです。コンパイルすると、WinServiceClass.exeが生成されますので、「WinServiceClass -install」でインストール、「WinServiceClass -remove」でアンインストールします。SCMには「WinService Test Program」という名前で表示されます。開始すると、5秒おきにメッセージが出ます。

今回のプログラムは、サービスプログラムとしては、最も単純な実装だと思います。エラー取得もイベントログ出力もありません。実際にはもっともっといろいろと機能が必要になってきます。そのあたりは、以下の参考サイトが参考になるかと思います。(英語ですが)この中で私が参考にしたのは、参考サイト2のプログラムです。

参考サイト1(海外)
The Code Project Interacting with the Operating System

参考サイト2(参考サイト1の中)
CNTService v1.06 - NT Service Framework

VC++のファイル一式を以下に置きました。
プロジェクトファイル一式

動作確認はしましたが、動作は保証できません。このプログラムを利用しての不具合、不利益には一切の責任を負いかねます。ご了承ください。


Windowsプログラミング関連記事