I’ve got a service project in Visual Studio 2005 that was converted to a Visual Studio 2010 project. And I’ve noticed a problem with the PreMessageLoop function, which looks like this:
HRESULT CMyModule::PreMessageLoop (int nShowCmd)
{
HRESULT result = CAtlServiceModuleT<CMyModule,100>::PreMessageLoop(nShowCmd);
if (ERROR_SUCCESS == result)
{
ComplicatedInitialization();
_AtlModule.SetServiceStatus (SERVICE_START_PENDING);
MoreComplicatedInitialization();
_AtlModule.SetServiceStatus (SERVICE_START_PENDING);
StillMoreComplicatedInitialization();
_AtlModule.SetServiceStatus (SERVICE_START_PENDING);
EvenMoreComplicatedInitialization();
}
return result;
}
This works great in Visual C++ 2005: The Run function calls my PreMessageLoop, which calls the base-class PreMessageLoop. The complicated initialization happens when the service is in SERVICE_START_PENDING. When my PreMessageLoop returns, Run calls SetServiceStatus(SERVICE_RUNNING).
Visual C++ 2010 is different: the base-class PreMessageLoop calls SetServiceStatus(SERVICE_RUNNING). The complicated initialization happens when the service is in SERVICE_RUNNING state, which is not good (because the service looks like it is running when it is in fact still initializing).
Can I simply move the base-class PreMessageLoop call to the bottom of my PreMessageLoop call? Or is it more complicated than a simple move?
Followup
It appears that a service can go from the SERVICE_RUNNING state back to the SERVICE_START_PENDING state. Is that wise?
First of all, “if (ERROR_SUCCESS == result)” is something not quite correct, as you should be checking result against HRESULT values, that is against
S_OK,S_FALSE, or usingSUCCEEDEDsort of macros.Base
PreMessageLoopis registering COM class objects, if your complicated initialization is not using COM instanatiation you are free to move your stuff above__super::PreMessageLoopcall.