6.6 - Breaking Changes - Service Tools Library

Release 6.6 of The Server Framework includes some breaking changes to both the IService, IServiceCallbacks and IShutdownService interfaces. Many functions now return an ServiceTools::ExitCode, either directly or by value, which allows you to fine tune the exit code returned from your service under failure conditions. This exit code is reported to the Service Control Manager (SCM) when your service shuts down and also returned from the exe if you run the service as a normal exe. These changes allow finer control of your service but can easily be completely ignored if you want things to stay the way they were.

Other functions take slightly different parameters

The changes

IService has two functions with new signatures.

      virtual int ParseServiceSpecificCommandLineArgument(
         PTSTR *ppArgv,
         const int nArgc,
         const int index,
         JetByteTools::Win32::_tstring &errorMessage,
         int &result) = 0;

      virtual bool CheckWeCanRun(
         const RunAction runAction,
         const JetByteTools::Win32::_tstring &errorMessageHeader,
         const IDisplayMessageBox &messageBoxDisplayer,
         int &result) = 0;

become

      virtual int ParseServiceSpecificCommandLineArgument(
         PTSTR *ppArgv,
         const int nArgc,
         const int index,
         JetByteTools::Win32::_tstring &errorMessage,
         ServiceTypes::ExitCode &result) = 0;

      virtual bool CheckWeCanRun(
         const RunAction runAction,
         const JetByteTools::Win32::_tstring &errorMessageHeader,
         const IDisplayMessageBox &messageBoxDisplayer,
         ServiceTypes::ExitCode &result) = 0;

Where you may have previously been returning 1 as the result from ParseServiceSpecificCommandLineArgument() you now need to return ServiceTypes::ExitSuccess, which happens to be 0, so be careful! Likewise with CheckWeCanRun() and note that you now also get given an interface which allows you to display an error message box. This will “do the right thing” if you are running as a service and simply add the message to your log, but if you’re running as an exe you’ll get a message box.

The changes in IServiceCallbacks are similar.

      virtual bool InitialiseService(
         IShutdownService &shutdown,
         INotifyProgress &notify,
         IManageServiceNotifications &notificationManager,
         const DWORD argc,
         const PTSTR *ppArgv) = 0;

      virtual void UninitialiseService(
         INotifyProgress &notify) = 0;

      virtual void OnException(
         const JetByteTools::Win32::CException &e) = 0;

      virtual void OnException(
         const JetByteTools::Win32::CSEHException &e) = 0;

      virtual void OnException(
         const std::exception &e) = 0;

      virtual void OnException() = 0;

      virtual bool InstallPerformanceCounters(
         JetByteTools::Win32::_tstring &errorMessage);

      virtual bool RemovePerformanceCounters(
         JetByteTools::Win32::_tstring &errorMessage);

Becomes

      virtual ServiceTypes::ExitCode InitialiseService(
         IShutdownService &shutdown,
         INotifyProgress &notify,
         IManageServiceNotifications &notificationManager,
         const DWORD argc,
         const PTSTR *ppArgv) = 0;

      virtual ServiceTypes::ExitCode UninitialiseService(
         INotifyProgress &notify) = 0;

      virtual ServiceTypes::ExitCode OnException(
         const JetByteTools::Win32::CException &e) = 0;

      virtual ServiceTypes::ExitCode OnException(
         const JetByteTools::Win32::CSEHException &e) = 0;

      virtual ServiceTypes::ExitCode OnException(
         const std::exception &e) = 0;

      virtual ServiceTypes::ExitCode OnException() = 0;

      virtual bool OnInstallPerformanceCounters(
         JetByteTools::Win32::_tstring &errorMessage) = 0;

      virtual bool OnRemovePerformanceCounters(
         JetByteTools::Win32::_tstring &errorMessage) = 0;

You can now report custom failure codes from exception handlers if you want to and also from the initialisation and shutdown code.

Finally a service initiated shutdown via the Shutdown() method of the IShutdownService interface can also report a custom exit code. This function has changed from this:

      virtual void Shutdown() = 0;

to this:

      virtual void Shutdown(
         const ServiceTypes::ExitCode exitCode = ServiceTypes::ExitSuccess) = 0;