2011-10-24 23 views
0

Visual Studio 2010でVisual Studio 2010プロジェクトに変換されたサービスプロジェクトがあります。これは、Visual C++ 2005で素晴らしい作品PreMessageLoopをオーバーライドする場合は、CAtlServiceModuleT :: PreMessageLoopを呼び出す必要があります

::Run関数は基底クラスPreMessageLoopを呼び出して、私のPreMessageLoopを呼び出します。そして、私はこのようになりますPreMessageLoop機能に問題があることを、気づきました複雑な初期化は、サービスがSERVICE_START_PENDINGになったときに発生します。私のPreMessageLoopが返ってくると、RunはSetServiceStatus(SERVICE_RUNNING)を呼び出します。

Visual C++ 2010は異なります。基本クラスのPreMessageLoopはSetServiceStatus(SERVICE_RUNNING)を呼び出します。複雑な初期化は、サービスがSERVICE_RUNNING状態にあるときに発生します。実際にはまだ初期化されているときに実行されているように見えます。

基本クラスのPreMessageLoop呼び出しをPreMessageLoop呼び出しの最後に移動できますか?それとも、単純な動きより複雑ですか?

フォロー

サービスがバックSERVICE_START_PENDING状態にSERVICE_RUNNING状態から行くことができると思われます。それは賢明ですか?すべての

答えて

1

まず、「(ERROR_SUCCESS ==結果)場合は、」あなたはHRESULT値に対する結果を確認する必要があるとして、それはS_OKS_FALSEに反している、またはマクロのSUCCEEDED並べ替えを使用して、非常に正確ではない何かです。

ベースPreMessageLoopはCOMクラスオブジェクトを登録していますが、複雑な初期化ではCOMを使用していない場合は、__super::PreMessageLoop呼び出し以上のものを自由に移動できます。 COMサポートを無効にします。PreMessageLoopで

+0

複雑な初期化の中には、SQL Server CompactまたはSQL ServerまたはOracleを呼び出して内部オブジェクト全体を初期化するものがあります。 SQL Serverの呼び出しはCOMを経由します。それは "COM instanatiationの使用"ですか? –

+0

内部COMオブジェクトのインスタンス化が必要な場合に、この単純な解決策があなたのためには機能しない場合でも、PreMessageLoop全体をオーバーライドして祖先からコピーし、祖先をもう呼び出さないでください。初期のSetServiceStatus呼び出しをコメントアウトし、初期化を完了したときにのみ実行中の状態を通知します。これにより、2005/2008 ATLと同じようになります。 –

0

COMの初期化コードは、エラー1053

ソリューション1を引き起こしています。

#define _ATL_NO_COM_SUPPORT 

"stdafx.h"には、すべてのATL関連が含まれています。

解決策2: "PreMessageLoop"を上書きし、COM初期化コードから削除します。

HRESULT PreMessageLoop(_In_ int nShowCmd) throw() 
{ 
    if (m_bService) 
    { 
     // Make sure that service was not stoped during initialization 
     if (::InterlockedCompareExchange(&m_status.dwCurrentState, SERVICE_RUNNING, SERVICE_START_PENDING) == SERVICE_START_PENDING) 
     { 
      LogEvent(_T("Service started/resumed")); 
      ::SetServiceStatus(m_hServiceStatus, &m_status); 
     } 
    } 

    // Start the tread(s) 
    _worker = new CWorkerThread(); 

    return S_OK; 
} 
関連する問題