Click here to Skip to main content
Click here to Skip to main content

A general purpose NT Service Class

, 6 Jul 2004 CPOL
Rate this:
Please Sign up or sign in to vote.
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)

Share

About the Author

Stefan Voitel

Germany Germany
No Biography provided

Comments and Discussions

 
QuestionGood Job, I needed a quick class to use Pinprofessionaldennislx19-Sep-14 12:50 
GeneralA thank you PinmemberCrin21-Oct-08 7:01 
GeneralFix for VC 2005 PinmemberEddy Luten2-Oct-07 12:47 
GeneralLanguage. Multi-Instance PinmemberYaroslav Sterkhov10-Jun-06 16:30 
QuestionThread-safe? Pinmembernoberg14-Feb-06 5:16 
GeneralTray Icon Pinmembercurious_ambitious16-Dec-05 4:07 
GeneralRe: Tray Icon PinmemberStefan Voitel19-Dec-05 12:12 
GeneralRe: Tray Icon PinmemberYaroslav Sterkhov10-Jun-06 16:25 
GeneralUNICODE PinmemberIlgar12-Dec-04 3:17 
Generalsamples in MSVC 6.0 format Pinmemberwangjlm25-Sep-04 4:40 
Could you please provide your samples in MSVC v6.0 format, I got same compilation problems with MSVC 2005 beta.

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.1411023.1 | Last Updated 7 Jul 2004
Article Copyright 2004 by Stefan Voitel
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid