So you want to write a service…
Posted by: Christian Wimmer in: Common
If you are going to write a service you should consider why you need it to be a service at all. If you can run your application as a standard user, you should do it. A service is a high privileged application that should be created with care and clear thoughts.
So think about your task you want to solve with the application.
- Do you need special privileges (e.g. TCB) that only a SYSTEM user can give?
- Do you have to keep secrets in a real safe area?
- Do you want to support multiple logged on users?
- Can the user profit from your service?
- Has the application to be active and available all the time?
You should say at least Yes twice to have a real reason.
Okay, but you want to get into that domain first. So what should you think of:
- A service is like a thread that has an execute method and if this method is exits, the service exits. There is no loop by default!
- A service cannot communicate with the user through a GUI. In preVista Windows versions, this “feature” was only a coincidence which frankly was used quite often (in fact everybody used it). It does not work for Remote desktop Logins or FastUserSwitch [Try out the following: Write a service that displays a standard message box and run it. Then switch to another user using FUS. You won't see the messageboxon the second user's desktop because it is on the first desktop (different sessions!). ].
- Use any log mechanism to give status report. Delphi offers the Windows event report mechanism by the method LogMessage.
- Use the method ProcessRequests if you go into a loop. This method lets the service respond to the requests of the Windows service control manager. If you just call Sleep your service will be unresponsible.
- The MessageBox API can show a message box on the current user’s desktop. To make it work add the flag MB_SERVICE_NOTIFICATION to the last parameter. You should also add MB_DEFAULT_DESKTOP_ONLY , so the messagebox only appears on the user’s desktop and not on the winlogon or any other desktop. Be aware that in this way you can only show one message at a time. The next message won’t appear until the first message has been clicked away.In my opinion this API is only good for debugging purposes. Think of a computer which does not have a logged on user. No administrator will every see your message.
There is an extended MessageBox API called WTSSendMessage. With this simple function you can easily chose in which session the messagebox is shown.
- You cannot debug a service like any other application by default. Luckily there is remedy. The JEDI API offers a RunAsSys application that lets you start your Delphi in the SYSTEM context. In this way you just have to do a minor patch to your service source code to make it run like any other application in Delphi. See my post Debugging services: an easy way.
There can be thousands of other good advices you should consider. However I didn’t want to scare you away. Just be aware of the upcoming (possible) problems and try to learn, learn and learn and ….
If you want to give another good advice, post it here.
Services isolation in Session 0 of Windows Vista and Longhorn Server