2005-10-04 16:39 i282 [permalink]
I've been searching on this for a while, and still I'm not sure I'm there all the way yet. For now I'll put a summary here of how to set op COM-object(s) from an NT-service.
Create a new NT-Service project in Delphi.
Add dependency "RpcSs".
Add a Type Library and COM-Objects (or Automation objects or anything COM/ActiveX really).
The objects need to be instancing type MultiInstance.
Add these registry keys (I'll use the regedit export notation for now, with a little imagination you can guess what the Delphi code might look like), replace {AppID} with the full class GUID of your main object (or a unique AppID if you already have one), and ServiceName is the name of your service (Name property of your TService).
[HKEY_CLASSES_ROOT\AppID\{AppID}]
"LocalService"="ServiceName"
[HKEY_CLASSES_ROOT\CLSID\{AppID}]
"AppID"="{AppID}"
Optionally you might rig the TService.AfterInstall/TService.AfterUninstall to call the DllRegisterServer/DllUnregisterServer calls, or vice versa (with overriding TAutoObjectFactory.UpdateRegistry).
Or be sure to have an install(/uninstall) program that does both.
Then, in the TService.ServiceStart include this:
CoInitializeSecurity(@CLASS_MyObject,-1,nil,nil,0,0,nil,8,nil);
Where CLASS_MyObject is the constant value for the same AppID GUID as described above.
When you want the service to run on a Windows Server 2003 computer, you need to fix one more thing. By default two internal system calls get mixed up. To fix this on older Delphi versions open the project's dpr, and move Application.Initialize;
to the TService.OnStart event handler. Newer versions of Delphi apparently have a notice in comment in the dpr, and also have a Application.DelayInitialization
property specifically for running COM objects from an NTService