Pages

Friday, September 3, 2010

Windows service using C

For a very long time I did not know what a windows service was. When I came to what it was, I thought I had learnt something important far too late. As they say, 'It is better to be late then never at all' ;) For people who don't know what a service is, A service is a console application that runs in the background and performs tasks that don't require user interaction. The Windows NT/2000/XP operating systems offer special support for service programs. The installed services can be configured through the Services applet, available from the Control Panel in Windows NT or from Control Panel | Administrative Tools in Windows 2000/XP. Services can be configured to start automatically when operating system starts, so you dont have to start each of them manually after a system reboot

Writing a windows service and installing on windows was a lot easier than I thought. This blog will explain how to write a simple windows service using C and install it.

A window's service program contains 3 parts,
  1. Main function
  2. Windows Service's Main function
  3. Control Handler function

The main function does nothing but lists the services that this program contains.
The program contain any number of services, the list must be terminated with a NULL entry into the list.

The Window's Service main is the entry point for your service.  This function should accomplish 3 things. It must set the appropriate status of the service using SetServiceStatus. The argument to the function is a SERVICE_STATUS. This function should register the controlhandler function for this service. The functionality of the control handler will be explained below. And finally, this function should not exit. If it does, the service will move to a 'STOPPED' state in the services applet.An ideal way of implementing this is using a while loop which checks for the state of the service status variable. (shown below).

The control handler handles the request to the service such as stopping it. Stopping the service can be triggered from the services applet. All cleanup code that the service must execute while exiting must be written here.

Sample Program,  SampleWindowsService.cpp

#include
#define SLEEP_TIME 5000

SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE hStatus;

void  ServiceMain(int argc, char** argv);
void  ControlHandler(DWORD request);

void main()
{
    SERVICE_TABLE_ENTRY ServiceTable[2];
    ServiceTable[0].lpServiceName = "MemoryStatus";
    ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;

    ServiceTable[1].lpServiceName = NULL;
    ServiceTable[1].lpServiceProc = NULL;
    // Start the control dispatcher thread for our service
    StartServiceCtrlDispatcher(ServiceTable); 
}

void ServiceMain(int argc, char** argv)
{
    int error;

    ServiceStatus.dwServiceType        = SERVICE_WIN32;
    ServiceStatus.dwCurrentState       = SERVICE_START_PENDING;
    ServiceStatus.dwControlsAccepted   =  SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
    ServiceStatus.dwWin32ExitCode      = 0;
    ServiceStatus.dwServiceSpecificExitCode = 0;
    ServiceStatus.dwCheckPoint         = 0;
    ServiceStatus.dwWaitHint           = 0;

    hStatus = RegisterServiceCtrlHandler(
        "MemoryStatus",
        (LPHANDLER_FUNCTION)ControlHandler);


    if (hStatus == (SERVICE_STATUS_HANDLE)0)
    {
        // Registering Control Handler failed
        return;
    } 

    // We report the running status to SCM.
    ServiceStatus.dwCurrentState = SERVICE_RUNNING;
    SetServiceStatus (hStatus, &ServiceStatus);

    MEMORYSTATUS memory;
    // The worker loop of a service
    while (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
    {
        Sleep(SLEEP_TIME);
    }
    return;
}

// Control handler function
void ControlHandler(DWORD request)
{
    switch(request)
    {
        case SERVICE_CONTROL_STOP:
            ServiceStatus.dwWin32ExitCode = 0;
            ServiceStatus.dwCurrentState  = SERVICE_STOPPED;
            SetServiceStatus (hStatus, &ServiceStatus);
            return;

        case SERVICE_CONTROL_SHUTDOWN:
            ServiceStatus.dwWin32ExitCode = 0;
            ServiceStatus.dwCurrentState  = SERVICE_STOPPED;
            SetServiceStatus (hStatus, &ServiceStatus);
            return;
       
        default:
            break;
    }

    // Report current status
    SetServiceStatus (hStatus,  &ServiceStatus);

    return;
}

To install this service on your operating system, you'll need to use the SC.EXE executable, which comes with the Win32 Platform SDK tools. You will use this utility to install and remove the service. The other control operations will be done through the Services applet.
Here is the command-line to install your windows service:

sc create SampleWindowsService binpath= 
c:\MyServices\SampleWindowsService.exe
 
To remove the service from the system, execute the following command:

sc delete SampleWindowsService

Specify the delete option and the service name. The service will be marked for deletion and will be completely removed after the next restart.

5 comments:

Vasu said...

hi rmn, I am moved by your inclination for CPP programming!
Writing services using C is fascinating dude! . I didnt get the application u r creating using this service .
Keep rockin man. sometimes i wonder i shud leave mba and come back to C/CPP.

Unknown said...

Vasu, the application does nothing actually. :) the code is taken from one of my projects, i removed the business logic of it and put only the service's skeleton.

As far as my fascination for C/C++ is concerned, it is only growing day after day !!

Anonymous said...

this article is a COPY of http://www.devx.com/cplus/Article/9857 i did not like that sorry!

- R. MAX

Anonymous said...

timberland boots, soccer shoes, nike roshe, asics running shoes, oakley, juicy couture outlet, beats by dre, new balance, jimmy choo shoes, vans, north face outlet, instyler, mcm handbags, abercrombie and fitch, baseball bats, hollister, karen millen, gucci, lancel, bottega veneta, valentino shoes, louboutin, reebok shoes, north face outlet, converse outlet, hollister, herve leger, juicy couture outlet, ralph lauren, ferragamo shoes, insanity workout, ghd, nike air max, mont blanc, chi flat iron, nfl jerseys, toms shoes, supra shoes, mac cosmetics, converse, babyliss, wedding dresses, celine handbags, ray ban, vans shoes, nike air max, montre pas cher, soccer jerseys, p90x workout, birkin bag

Unknown said...

How do you add the main logic for it tho?