Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A general purpose NT Service Class

0.00/5 (No votes)
6 Jul 2004 1  
Build a NT Service

Introduction

Apologies in advance about my English and the brief descriptions, as my native language is German. The TService class wraps all the things around a NT-Service and allows to create a NT-Service with a few lines of code.

TService

virtual void ServiceProc           (void) = PURE;

This is the main service procedure. If you leave ServiceProc() your service is stopped.

virtual const char* GetName        (void) = PURE;
virtual const char* GetDisplayName (void) {return GetName();}

Simply return a string to identify the service by name. You can also overwrite the GetDisplayName() procedure to install your service with a different display name.

bool          Execute        (void);

Run as Service. This should be the default call for your service from the main procedure.

bool          ConsoleMode    (void);

To check out a service you can run the service from a console window. The service runs in the logged on user account.

bool          Start          (void);
bool          Stop           (void);
bool          Install        (void);
bool          Remove         (void);
virtual bool  Help           (DWORD context = 0);

Control the service. Help() searches for a helpfile named "GetName().hlp"

bool          Terminated     (void;}
void          Terminate      (void;}

Your ServiceProc() must check Terminated() periodically to get a stop request. When Terminated() returns true you should leave the ServiceProc() und cleanup your Service. Call Terminate() to stop the Service from outside ServiceProc().

const char *  LastError      (void)  const {return m_ServiceError;}

Returns the last error as string from the system.

void          PrintLastError   (const char *Caption = NULL);

Writes the last error to the standard error device if any.

bool SetConfigValue (char* key,BYTE *value,DWORD nvalue,cfValType type = cfString);
bool GetConfigValue (char* key,BYTE *buf,DWORD *nbuff,cfValType *ypet);

    enum cfValType {
      cfBinary  = REG_BINARY,
      cfDword   = REG_DWORD,
      cfString  = REG_S
    };

Set and get Registry Values like RegSetValue() and RegQueryValue(). The values are located under : "HKLM\SYSTEM\CurrentControlSet\Services\%ServiceName%\ServiceConfig\".

void LogEvent       (char* event,evLogType type = evInfo,WORD category = 0);

   enum evLogType {
      evError   = EVENTLOG_ERROR_TYPE,
      evWarning = EVENTLOG_WARNING_TYPE,
      evInfo    = EVENTLOG_INFORMATION_TYPE
   };

Write to the SystemEventLog.

virtual bool Init             (void)       {return true;}

Is be called before ServiceProc(), you can setup your service here. If Init() returns false the service will stop.

virtual void Cleanup          (void)       {return;}

The service is stopped, cleanup resources from Init().

virtual void LogoffEvent      (void)       {return;}

A user has logged off. If you would check that a user is logged in search in ServiceProc() for a window named "Shell_TrayWnd".

virtual void ShutdownEvent    (void)       {Terminate();}

The Machine is shutting down, terminate the service.

Sample

Here is a short quick and dirty sample how to create a service. To control the service run the executable from the console with the parameters :

/install to install the service
/remove to remove the service from the system
/start to start the service
/quit to stop the service
/test

to test the service from a console window

#include "cService.hpp" // cService.h AND cService.cpp


class  cMyService : private TService {
 public:
   cMyService (char *arg);

 private:
   const char* GetName        (void){return "MyService";}
   void        ServiceProc    (void);
};

cMyService::cMyService (char *arg) {
if (arg != NULL) {
  unsigned short a = *((unsigned short*) arg);  

   if      (a == *((unsigned short*) "/i")) Install(); 
   else if (a == *((unsigned short*) "/r")) Remove();
   else if (a == *((unsigned short*) "/s")) Start();
   else if (a == *((unsigned short*) "/q")) Stop();
   else if (a == *((unsigned short*) "/t")) ConsoleMode();
   }
else Execute();
}

void cMyService::ServiceProc (void) {
while (! Terminated()) {
   Beep  (400,100);
   Sleep (5000);
   }
}

void main (int argc,char *argv[]) {
delete new cMyService(argv[1]);
}

History

  • July 7, 2004 - First release.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here