16 Dec
Posted by: Christian Wimmer in: Common
… to be called before CoRegisterClassObject, which can be called indirectly by Application.Initialize.
You can see this comment at the beginning of a newly created service application. Unfortunately, today it is only half of the truth.
If you like to create a DCOM server in a service, and this is really easy if you know how to create in-process COM objects, then you need to know that Microsoft has changed the precondition for service initialization.
StartServiceCtrlDispatcher reads:
If a service runs in its own process, the main thread of the service process should immediately call StartServiceCtrlDispatcher. All initialization tasks are done in the service’s ServiceMain function when the service is started.
Usually, the COM factories in Delphi register their classes before any of the user code is initialized. It is done in unit ComServ in procedure Initialization. There an initialization procedure (InitProc) is set for further processing.This is bad for services because the COM registration has to be done in the ServiceMain function (or just after the call) as MSDN states. If you ignore or forget it the creation of a COM object (in the client) fails after some time (usually some minutes) with the error
CO_E_SERVER_EXEC_FAILURE ($80080005) : Server execution failed
For this reason the comment was added to the service code:
// Windows 2003 Server requires StartServiceCtrlDispatcher to be // called before CoRegisterClassObject, which can be called indirectly // by Application.Initialize. TServiceApplication.DelayInitialize allows // Application.Initialize to be called from TService.Main (after // StartServiceCtrlDispatcher has been called). // // Delayed initialization of the Application object may affect // events which then occur prior to initialization, such as // TService.OnCreate. It is only recommended if the ServiceApplication // registers a class object with OLE and is intended for use with // Windows 2003 Server.
Well, what I didn’t realize, and that I really blame myself for, was the fact that this condition also exists in Windows Vista and Windows 7. So we need to set
Application.DelayInitialize := true;
not only in Windows Server 2003 but also in all new Windows versions like Vista, 7, 8 and so on. So don’t believe in what comments tell but start thinking… Lesson learned the hard way.
PS. Is it worth to file it in QC?
QC Report 4722 : Service exposing COM interface does not work on windows 2003; http://qc.embarcadero.com/wc/qcmain.aspx?d=4722
Leave a reply
You must be logged in to post a comment.