none
[CAtlServiceModuleT] VS2013 VC++ Windowsサービスが「開始中」のままで「実行中」に遷移できない対策方法について RRS feed

  • 質問

  • Visual Studio 2013で、
    ファイル/新規作成/テンプレート/Visual C++/ATL/ATLプロジェクト/サービス(EXE)
    から、WindowsサービスのATLProject1を作成しました。
    そして、
    ATLProject1.exe /UnregServer
    ATLProject1.exe /Service
    でWindowsサービスに登録した後、
    Windowsサービスの画面で、ATLProject1を開始しました。
    ところが、ずっと「開始中」のままで「実行中」に遷移できませんでした。
    その対策として、オーバライドしたRunMessageLoopの先頭に、以下の5行を追加しました。
            if (m_bService)
            {
                LogEvent(_T("Service started"));
                SetServiceStatus(SERVICE_RUNNING);
            }
    その結果、「開始中」は「実行中」に遷移できました。
    そこで、質問ですが、この対策でいいのでしょうか?
    以下、ソースコードです。
    ////////////////////////////////////////////////////////////////////////////////////////////////////
    // ATLProject1.cpp : WinMain の実装
    #include "stdafx.h"
    #include "resource.h"
    #include "ATLProject1_i.h"
    using namespace ATL;
    #include <stdio.h>
    class CATLProject1Module : public ATL::CAtlServiceModuleT< CATLProject1Module, IDS_SERVICENAME >
    {
    public:
        DECLARE_LIBID(LIBID_ATLProject1Lib)
        DECLARE_REGISTRY_APPID_RESOURCEID(IDR_ATLPROJECT1, "{C60FD0CF-753F-45BD-90D7-273EF79C3D17}")
        HRESULT InitializeSecurity() throw()
        {
            // TODO: CoInitializeSecurity を呼び出し、サービスのための適切なセキュリティ設定を指定します
            // 推奨 - PKT レベルの認証、
            // RPC_C_IMP_LEVEL_IDENTIFY の偽装レベル、
            // および適切な非 NULL セキュリティ記述子。
            return S_OK;
        }
        HRESULT PreMessageLoop(int nShowCmd) throw() {
            HRESULT hr = __super::PreMessageLoop(nShowCmd);
            //-----VC2008時の対策(ここから)-----
    #if _ATL_VER >= 0x0700
            if (SUCCEEDED(hr) && !m_bDelayShutdown) {
                hr = CoResumeClassObjects();
            }
    #endif
            //-----VC2008時の対策(ここまで)-----
            if (SUCCEEDED(hr)) {
                // 起動時の処理を書く
            }
            return hr;
        }
        void RunMessageLoop() throw()
        {
            //-----VC2013時の対策(ここから)-----
            if (m_bService)
            {
                LogEvent(_T("Service started"));
                SetServiceStatus(SERVICE_RUNNING);
            }
            //-----VC2013時の対策(ここまで)-----
            __super::RunMessageLoop(); //ここを自分の処理に書き換える
        }
    };
    CATLProject1Module _AtlModule;
    //
    extern "C" int WINAPI _tWinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/,
        LPTSTR /*lpCmdLine*/, int nShowCmd)
    {
        return _AtlModule.WinMain(nShowCmd);
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////
    2017年6月10日 13:37