To the main page...The list of my products...Some texts...Sample applications, tips, tricks...If you need support...
 

 
DCOM server in Windows NT Service
The DCOM server "near" Windows NT service

Let's consider the simple example of application that looks as a DCOM server in a service. To create it do the following

1) Create new service application. Use Delphi IDE File|New dialog box for this purpose. Set the name of the service created 'SvcWithComServer'.

2) Create a new AutoObject using ActiveX page of File|New dialog box. Set it`s name to SvcObject.

3) Add an Execute method to the ISvcObject interface. Set the return type of this function to WideString and implement it. It should return any sting you wish. It will be used for tests only.

4) Compile and install your application. Use -install switch to install it.

5) Create a sub-key of HKEY_CLASSES_ROOT\AppID key. Set it's name to the value of our type library GUID. Of course you can generate a new one but for our purposes it is not necessary and it does not affect the results. Add a new string value to the sub-key created. Set the name of this value to 'LocalService' and the value to 'SvcWithComServer'. Also add an AppID value to the CLSID key of our object. The text of this value should be the same as the GUID that was used on previous step.

Now our example is ready for testing. It should look like this (4Kb zip)

We need a sample client application to test our server. It may be any application with a form and a button on it. The XXX_TLB unit should be added to the uses section of it. The OnClick handler for the button should look like ShowMessage(CoSvcObject.Create.Execute); The resulting application should look like this one (2Kb zip).

Try to run the client application and press the button. You will see the message box with the string that our SvcObject returns. Check also that the service is started. Is it working ? It seems to...

Here is a list of absolutely legal actions any of which causes our example to stop working

  • It does not work if the client has no rights to start or access the DCOM. Change the default security options using DcomCnfg and check it.
  • The com-server continues to work even after the service stops. To check it add an additional empty service to our example and start it. This will cause the application to stay in memory while the first service is stopped.
  • Try to change the RunAs settings for our com-object and you will loose ability to start it at all. Moreover you will loose the ability to uninstall the service.

This list can be continued.

Now let's try to understand what happens with our example. Take a look on the ComServ unit. This unit is a kernel of our com-server. It performs a lot of work. It forces classfactories to register and unregister their objects in registry. It registers and unregisters the IClassFactory interfaces at runtime. It monitors the total number of objects and stops application after the last object being released. The only one problem exists. The ComServ unit performs all these actions in the main thread of application. It is the thread that is entered first at application startup. Namely, all work mentioned above is performed during Application.Initialize call. It is a main problem. For the service application this main thread is not main at all. It has only one role - it must register entry point for each service. After this registration it does nothing, it is absolutely useless. Delphi implementation design of SvcMgr does not stop this thread, it continues to work until the last thread being stopped. The only work of this thread is to check the returned values of services and write the errors to event-log. It means that all work that is necessary to instantiate DCOM server is performed in an additional, non-functional thread. This thread is not a service, it can not be controlled like a service can be. Now it is clear why our server behaves so strange. That is why I call such DCOM server as "DCOM server near service".

<< | Index | 1 | 2 | 3 | 4 | 5 | >>
 

 
© 1998-2001 Alexey Dynnikov
My ICQ # is 18267212