Click here to Skip to main content
15,867,686 members
Articles / Programming Languages / C++
Article

A general purpose NT Service Class

Rate me:
Please Sign up or sign in to vote.
4.59/5 (20 votes)
6 Jul 2004CPOL2 min read 61.4K   3.1K   43   10
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionGood Job, I needed a quick class to use Pin
dennislx19-Sep-14 11:50
professionaldennislx19-Sep-14 11:50 
GeneralA thank you Pin
Crin21-Oct-08 6:01
Crin21-Oct-08 6:01 
GeneralFix for VC 2005 Pin
Eddy Luten2-Oct-07 11:47
Eddy Luten2-Oct-07 11:47 
GeneralLanguage. Multi-Instance Pin
Yaroslav Sterkhov10-Jun-06 15:30
Yaroslav Sterkhov10-Jun-06 15:30 
QuestionThread-safe? Pin
noberg14-Feb-06 4:16
noberg14-Feb-06 4:16 
GeneralTray Icon Pin
curious_ambitious16-Dec-05 3:07
curious_ambitious16-Dec-05 3:07 
GeneralRe: Tray Icon Pin
Stefan Voitel19-Dec-05 11:12
Stefan Voitel19-Dec-05 11:12 
Hi Martin,

Yes and it work under NT4 and w2k but not under Windows XP.
In my oppinion the better solution is write a application and let it comunicate with the the service through pipes (or so) and place it in any autostart.

best regards stefan
GeneralRe: Tray Icon Pin
Yaroslav Sterkhov10-Jun-06 15:25
Yaroslav Sterkhov10-Jun-06 15:25 
GeneralUNICODE Pin
Ilgar12-Dec-04 2:17
Ilgar12-Dec-04 2:17 
Generalsamples in MSVC 6.0 format Pin
singwg25-Sep-04 3:40
singwg25-Sep-04 3:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.