【ATL】Windowsのサービスを作成する


概要

Visual Studio 2019のATLプロジェクトを使用してWindowsのサービスを作成します。

新しいプロジェクトの作成

  1. Visual Studio 2019を起動し、[新しいプロジェクトの作成]を選択します。

  2. [ATLプロジェクト]を選択して、[次へ]を押します。

  3. [プロジェクト名]を入力します。ここでは"ATLServiceSample"とします。
    必要に応じて[場所]も設定します。
    またお好みで[ソリューションとプロジェクトを同じディレクトリに配置する]にチェックを入れます。
    設定が終わったら[作成]を押します。

  4. [アプリケーションの種類]で[サービス(.exe)]を選択し、[OK]を押します。

これでプロジェクトが作成されました。
私はプロジェクト作成後に下記を行っていますが、必須ではありません。

  • ATLServiceSamplePSプロジェクトの削除
  • [ATLServiceSamplePS]フォルダを中のファイルごと削除
  • ATLServiceSampleプロジェクトのプロパティにおいて下記を設定。
    • [構成プロパティ]→[C/C++]→[コード生成]:[ランタイムライブラリ]=[マルチスレッド]
    • [構成プロパティ]→[リンカー]→[全般]:[出力の登録]=[いいえ]

実行ファイルの作成

  1. 現時点ではCOMを使っていないので、"_ATL_NO_COM_SUPPORT"を定義しておきます。
    [構成プロパティ]→[C/C++]→[プリプロセッサ]:[プロプロセッサの定義]に追加しても、ソースコード上で定義しても構いませんが、私は前者にしました。
    COMオブジェクトが未実装&この定義が無い状態だと、サービス実行時、メインループに入らずに下記のメッセージが出てしまいます。

  2. この時点でもサービスとして動きますが、これからサービス処理を実装していくにあたって必要な関数を追加しておきます。
    追加する関数は、下記の3つです。

  • PreMessageLoop : 初期化処理
  • RunMessageLoop : メイン処理
  • PostMessageLoop : 終了処理
ATLServiceSample.cpp
class CATLServiceSampleModule : public ATL::CAtlServiceModuleT< CATLServiceSampleModule, IDS_SERVICENAME >
{
public :
    DECLARE_LIBID(LIBID_ATLServiceSampleLib)
    DECLARE_REGISTRY_APPID_RESOURCEID(IDR_ATLSERVICESAMPLE, "{20521712-cd2f-409a-8fb7-c1cf9957b0d5}")
    HRESULT InitializeSecurity() throw()
    {
        // TODO: CoInitializeSecurity を呼び出し、サービスのための適切なセキュリティ設定を指定します
        // 推奨 - PKT レベルの認証、 
        // RPC_C_IMP_LEVEL_IDENTIFY の偽装レベル
        // および適切な非 NULL セキュリティ記述子。

        return S_OK;
    }

#if 1 // ここから追加
    // 初期化
    HRESULT PreMessageLoop(_In_ int nShowCmd) throw()
    {
        HRESULT hr = __super::PreMessageLoop(nShowCmd);
        if (SUCCEEDED(hr))
        {
            // ToDo: ここに初期化処理を実装する
        }
        return hr;
    }

    // メイン処理
    void RunMessageLoop() throw()
    {
        // ToDo: ここをサービスの内容に応じて変更する
        MSG msg;
        while (GetMessage(&msg, 0, 0, 0) > 0)
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    // 終了処理
    HRESULT PostMessageLoop() throw()
    {
        // ToDo: ここに終了処理を実装する

        return __super::PostMessageLoop();
    }
#endif // ここまで追加
};
  1. プロジェクトをビルドします。
    ソリューション構成&プラットフォームは何でも構いませんが、私はReleaseのx64でビルドしました。

サービスの登録

  1. 管理者として実行したコマンドプロンプトから下記のコマンドを実行します。
    "D:\Work\ATLServiceSample\x64\Release\ATLServiceSample.exe" /Service
    ※ 実行ファイルのパスはそれぞれの環境のものを使用してください。

  2. スタートメニューから[Windowsツール]→[サービス]を開き、[ATLServiceSample]が登録されていればOKです。