EXT Win Library - service

The win::service class abstracts all the Windows API calls neccessary to implement a service and/or to control the service.


Interface:

class win::service {
    public:
        enum flags {
            can_be_paused = 0x01,
            receive_device_events = 0x02,
            receive_power_events = 0x04,
            receive_hardware_events = 0x08,
            receive_session_events = 0x10,
        };

    protected:
        const bool & as_console;

    protected:
        explicit service (const std::string &, flags = static_cast <flags> (0));
        virtual ~service () throw ();

        void step () throw ();

    private:

        // Interface for implementation of services

        virtual void main () = 0;

        virtual bool on_initialize (void *);
        virtual void on_pause ();
        virtual void on_resume ();
        virtual void on_stop ();
        virtual void on_shutdown ();

        virtual bool on_command (unsigned int);

        virtual void on_device_event (unsigned int, void *);
        virtual bool on_power_event (unsigned int);
        virtual void on_session_change (unsigned int, unsigned int);
        virtual bool on_hardware_change (unsigned int);

    private:
        service (const service &);
        service * operator = (const service &);

    public:

        // Interface for controlling the service

        void run () throw ();

        void install (const std::string &) throw (ext::runtime_error);
        void remove () throw (ext::runtime_error);
        void set_description (const char *) throw (ext::runtime_error);
        void set_description (const wchar_t *) throw (ext::runtime_error);
        void set_autostart (bool) throw (ext::runtime_error);

        void start () throw (ext::runtime_error);
        void stop () throw (ext::runtime_error);

        bool command (unsigned int) throw (ext::runtime_error);
};

Service implementation specific member functions

Service control specific member functions

Details:

To use the win::service a concrete service class must be derived from win::service.

For both uses, the actual service process and service-controller process, the win::service base must be constructed with the same flags. Otherwise the misconfigured features may not be available or may not work properly. The behavior in this case is intentionally left undefined so it can change in future versions.

The win::service object cannot be copied.
In order to use win::service, the following files need to be included into the project:

Examples:

#include <ext/win>
#include <csignal>

class service_type : public win::service {
    private:
        static void signal_handler (int);
        static const char * name;

    private:
        volatile bool quit;

    private:
        virtual void on_stop () {
            this->quit = true;
        };
        virtual void main () {
            while (!this->quit) {

            // ...

            };
            return;;
        };

    public:
        service_type ();

} service;

void service_type::signal_handler (int) {
    service.quit = true;
};

service_type::service_type ()
    :   win::service (name),
        quit (false) {

    std::signal (SIGINT, &service_type::signal_handler);
    std::signal (SIGTERM, &service_type::signal_handler);
    std::signal (SIGBREAK, &service_type::signal_handler);
};

const char * service_type::name = "Test Service";

int main () {
    service.run ();
    return 0;
};

The example above shows also how to gracefuly terminate the process on break signals (Ctrl+C, ...) when not running as a service. Also note that second such signal forces the termination of the process anyway.

Remarks

Note that to inherit in order to reuse (as you need to in order to use win::service) is not a best practice. Prefer to inherit in order to be reused.

The win::service always accepts a shutdown and stop commands by design.

See MSDN (Platform SDK) for more details regarding Windows Services.


[index]