Changes to the Service Tools library in 6.3

The development of WASP has been acting as a bit of an internal driver for new feature development in the 6.3 release of The Server Framework. Sitting down to develop a service that was easy to use for a mass market exposed some small holes in the 6.2 release; nothing too serious but pretty soon after putting together the first service shell of the WASP application I had a list of nice to have additions for the Service Tools Library.

The first issue that I came across was how the service’s debug log was created was a little bit complicated. Prior to the 6.3 code the service would start and create a debug log in the windows temp directory with a default name, then as it got further into its start up phase it would read its config file and open a new log file in the place where the config file said it should. The user would likely not be aware of the original log file and whilst you very rarely needed to look at it it could be helpful if the service failed very early in its start up sequence. The reason for two logs was that it was complex to load the config file earlier in the start up sequence because we only parsed the command line when we were about to execute the service code and there was a lot happening before this point. The solution to this issue was to parse the command line earlier and simply store what we need to do when we execute the service code rather than parsing and executing at the same time. This allows us to know enough about the service (specifically the instance we’re working with) much earlier in the start up sequence and so we can then read the per instance config information and create the correct log file straight away.

Next I changed the /debug command line argument to /run, recognising that whilst the ability to run the service as a normal exe was originally added to allow easy debugging from within Visual Studio it’s equally useful to be able to run the app as an exe sometimes and so the feature should be officially recognised. It naturally followed that running the exe with no command line arguments could and probably should imply /run. So now you can run a service as an exe just by running it as an exe… You only need an explicit /run if you’re dealing with an instance.

The Service Tools Library can build services that can be run as multiple instances and those that can not; there may be a reason that you don’t want to allow multiple instances and you can decide when you’re building the code if this functionality is supported or not. Anyway, in 6.2 you always needed to specify the instance name for a service that could have separate instances. This meant that for a service which you wanted to run as an exe you would always need to use /run [name] and could never simply run the exe. I’ve added the concept of a “default” instance. Again you can select this whilst building the code if it’s appropriate and if so then any instance related command lines that don’t specify an explicit instance name use the default instance name. This makes services which support instances easier to use from the command line if you’re only interested in a single instance; you now simply ignore the instance name altogether.

I’ve added an explicit “help” command line option, previously you’d get help if you entered an invalid command line, now you can request help explicitly by calling the exe with /? or /help. Of course there’s very little difference, apart from the wording of the dialog box, between 6.2 without explicit help and 6.3 with as in 6.2 /? and /help were unknown command line options and so would trigger a help display anyway.

Next I added service specific command line options. You can now add your own command line parsing code which is passed arguments that the library code doesn’t understand. You can also provide your own custom help strings for your custom command line options.

The changes to how instance names are dealt with and the default instance had a knock on effect on the hidden command line option that’s used to run the service as a service. In 6.2 this was different for services that supported instances and services that didn’t. In 6.3 the same command line option is used for both. This means that you must remove and reinstall any services that you upgrade from 6.2 to 6.3.

I’ve cleaned up how we deal with “Access denied” errors and elevation. Now all installation operations that require elevation will prompt you for it rather than only /install doing so. Also the elevation prompt is now displayed prominently and has focus whereas in 6.2 it was minimised and without focus. This was a lucky break, I had no idea why the elevation prompt behaved as it did in 6.2 but whilst looking into another possible change in 6.3 I attached the service to the console, using ::AttachConsole(ATTACH_PARENT_PROCESS); and suddenly the elevation prompt started to behave as I would have expected it to. No doubt it’s all to do with parent windows…

Since I’m expecting to be dealing with more support requests due to a larger user base all message boxes are now logged to the service debug log.

To allow the service programmatic control of its own shutdown there’s now an IShutdownService interface.

Finally there’s a new exception handler in IServiceCallbacks which handles std::exception.

These changes are included in version 6.3 of The Server Framework which is released today.