Click here to Skip to main content
11,923,046 members (63,756 online)
Click here to Skip to main content
Add your own
alternative version


134 bookmarked

Simple Windows Service in C++

, 30 May 2013 CPOL
Rate this:
Please Sign up or sign in to vote.
An article that shows how to create a simple Windows service in C++.


This article shows how to create a basic Windows Service in C++. Services are very useful in many development scenarios depending on the architecture of the application.


There are not many Windows Service examples that I found in C++. I used MSDN to write this very basic Windows service.

Using the code

At a minimum a service requires the following items:

  • A Main Entry point (like any application)
  • A Service Entry point
  • A Service Control Handler

You can use a Visual Studio template project to help you get started. I just created an "Empty" Win32 Console Application.

Before we get started on the Main Entry Point, we need to declare some globals that will be used throughout the service. To be more object oriented you can always create a class that represents your service and use class members instead of globals. To keep it simple I will use globals.

We will need a SERVICE_STATUS structure that will be used to report the status of the service to the Windows Service Control Manager (SCM).

SERVICE_STATUS        g_ServiceStatus = {0}; 

We will also need a SERVICE_STATUS_HANDLE that is used to reference our service instance once it is registered with the SCM.


Here are some additional globals and function declarations that will be used and explained as we go along.

SERVICE_STATUS        g_ServiceStatus = {0};
HANDLE                g_ServiceStopEvent = INVALID_HANDLE_VALUE;
VOID WINAPI ServiceMain (DWORD argc, LPTSTR *argv);
VOID WINAPI ServiceCtrlHandler (DWORD);
DWORD WINAPI ServiceWorkerThread (LPVOID lpParam);
#define SERVICE_NAME  _T("My Sample Service")    

Main Entry Point

int _tmain (int argc, TCHAR *argv[])
    SERVICE_TABLE_ENTRY ServiceTable[] = 
        {NULL, NULL}
    if (StartServiceCtrlDispatcher (ServiceTable) == FALSE)
        return GetLastError ();
    return 0;

In the main entry point you quickly call StartServiceCtrlDispatcher so the SCM can call your Service Entry point (ServiceMain in the example above). You want to defer any initialization until your Service Entry point, which is defined next.

Service Entry Point

VOID WINAPI ServiceMain (DWORD argc, LPTSTR *argv)
    DWORD Status = E_FAIL;
    // Register our service control handler with the SCM
    g_StatusHandle = RegisterServiceCtrlHandler (SERVICE_NAME, ServiceCtrlHandler);
    if (g_StatusHandle == NULL) 
        goto EXIT;
    // Tell the service controller we are starting
    ZeroMemory (&g_ServiceStatus, sizeof (g_ServiceStatus));
    g_ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
    g_ServiceStatus.dwControlsAccepted = 0;
    g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
    g_ServiceStatus.dwWin32ExitCode = 0;
    g_ServiceStatus.dwServiceSpecificExitCode = 0;
    g_ServiceStatus.dwCheckPoint = 0;
    if (SetServiceStatus (g_StatusHandle , &g_ServiceStatus) == FALSE)
          "My Sample Service: ServiceMain: SetServiceStatus returned error"));
     * Perform tasks necessary to start the service here
    // Create a service stop event to wait on later
    g_ServiceStopEvent = CreateEvent (NULL, TRUE, FALSE, NULL);
    if (g_ServiceStopEvent == NULL) 
        // Error creating event
        // Tell service controller we are stopped and exit
        g_ServiceStatus.dwControlsAccepted = 0;
        g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
        g_ServiceStatus.dwWin32ExitCode = GetLastError();
        g_ServiceStatus.dwCheckPoint = 1;
        if (SetServiceStatus (g_StatusHandle, &g_ServiceStatus) == FALSE)
	      "My Sample Service: ServiceMain: SetServiceStatus returned error"));
        goto EXIT; 
    // Tell the service controller we are started
    g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
    g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
    g_ServiceStatus.dwWin32ExitCode = 0;
    g_ServiceStatus.dwCheckPoint = 0;
    if (SetServiceStatus (g_StatusHandle, &g_ServiceStatus) == FALSE)
          "My Sample Service: ServiceMain: SetServiceStatus returned error"));
    // Start a thread that will perform the main task of the service
    HANDLE hThread = CreateThread (NULL, 0, ServiceWorkerThread, NULL, 0, NULL);
    // Wait until our worker thread exits signaling that the service needs to stop
    WaitForSingleObject (hThread, INFINITE);
     * Perform any cleanup tasks 
    CloseHandle (g_ServiceStopEvent);
    // Tell the service controller we are stopped
    g_ServiceStatus.dwControlsAccepted = 0;
    g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
    g_ServiceStatus.dwWin32ExitCode = 0;
    g_ServiceStatus.dwCheckPoint = 3;
    if (SetServiceStatus (g_StatusHandle, &g_ServiceStatus) == FALSE)
          "My Sample Service: ServiceMain: SetServiceStatus returned error"));

The Service Main Entry Point performs the following tasks:

  • Initialize any necessary items which we deferred from the Main Entry Point.
  • Register the service control handler which will handle Service Stop, Pause, Continue, Shutdown, etc control commands. These are registered via the dwControlsAccepted field of the SERVICE_STATUS structure as a bit mask.
  • Set Service Status to SERVICE_PENDING then to SERVICE_RUNNING. Set status to SERVICE_STOPPED on any errors and on exit. Always set SERVICE_STATUS.dwControlsAccepted to 0 when setting status to SERVICE_STOPPED or SERVICE_PENDING.
  • Perform start up tasks. Like creating threads/events/mutex/IPCs/etc.

Service Control Handler

VOID WINAPI ServiceCtrlHandler (DWORD CtrlCode)
    switch (CtrlCode) 
        if (g_ServiceStatus.dwCurrentState != SERVICE_RUNNING)
         * Perform tasks necessary to stop the service here 
        g_ServiceStatus.dwControlsAccepted = 0;
        g_ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
        g_ServiceStatus.dwWin32ExitCode = 0;
        g_ServiceStatus.dwCheckPoint = 4;
        if (SetServiceStatus (g_StatusHandle, &g_ServiceStatus) == FALSE)
              "My Sample Service: ServiceCtrlHandler: SetServiceStatus returned error"));
        // This will signal the worker thread to start shutting down
        SetEvent (g_ServiceStopEvent);

The Service Control Handler was registered in your Service Main Entry point. Each service must have a handler to handle control requests from the SCM. The control handler must return within 30 seconds or the SCM will return an error stating that the service is not responding. This is because the handler will be called in the context of the SCM and will hold the SCM until it returns from the handler.

I have only implemented and supported the SERVICE_CONTROL_STOP request. You can handle other requests such as SERVICE_CONTROL_CONTINUE, SERVICE_CONTROL_INTERROGATE, SERVICE_CONTROL_PAUSE, SERVICE_CONTROL_SHUTDOWN and others supported by the Handler or HandlerEx function that can be registered with the RegisterServiceCtrlHandler(Ex) function.

Service Worker Thread

DWORD WINAPI ServiceWorkerThread (LPVOID lpParam)
    //  Periodically check if the service has been requested to stop
    while (WaitForSingleObject(g_ServiceStopEvent, 0) != WAIT_OBJECT_0)
         * Perform main service function here
        //  Simulate some work by sleeping
    return ERROR_SUCCESS;

This sample Service Worker Thread does nothing but sleep and check to see if the service has received a control to stop. Once a stop control has been received the Service Control Handler sets the g_ServiceStopEvent event. The Service Worker Thread breaks and exits. This signals the Service Main routine to return and effectively stop the service.

Installing the Service

You can install the service from the command prompt by running the following command:

C:\>sc create "My Sample Service" binPath= C:\SampleService.exe

A space is required between binPath= and the value[?]. Also, use the full absolute path to the service executable.

You should now see the service in the Windows Services console. From here you can start and stop the service.

Uninstalling the Service

You can uninstall the service from the command prompt by running the following command:

C:\>sc delete "My Sample Service"  


  • 11/28/2012: Initial release of article and code.
  • 11/29/2012: Improved code and fixed one typo in article sample code.
  • 11/03/2015: Updated details on how to install the service based on user comments.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Mohit Arora
Software Developer (Senior)
United States United States
No Biography provided

You may also be interested in...

Comments and Discussions

GeneralIt is simple Pin
NeverForever3-Nov-15 17:09
memberNeverForever3-Nov-15 17:09 
QuestionService Installation Pin
Pulathisi Bhathiya7-Aug-15 19:24
memberPulathisi Bhathiya7-Aug-15 19:24 
SuggestionInstruction on how to install service Pin
Eswar Yaganti31-Mar-15 0:22
memberEswar Yaganti31-Mar-15 0:22 
Questionpurpose of service Pin
Hamidreza Ebtehaj15-Mar-15 7:53
memberHamidreza Ebtehaj15-Mar-15 7:53 
AnswerRe: purpose of service Pin
Mohit Arora16-Mar-15 18:22
memberMohit Arora16-Mar-15 18:22 
GeneralRe: purpose of service Pin
Hamidreza Ebtehaj26-May-15 18:51
memberHamidreza Ebtehaj26-May-15 18:51 
GeneralMy vote of 5 Pin
JH6425-Feb-15 11:24
memberJH6425-Feb-15 11:24 
QuestionThe timeout problem Pin
brekehan18-Feb-15 12:47
memberbrekehan18-Feb-15 12:47 
AnswerRe: The timeout problem Pin
Mohit Arora18-Feb-15 15:09
memberMohit Arora18-Feb-15 15:09 
QuestionMy Vote 5 Pin
Member 1138251217-Jan-15 12:29
memberMember 1138251217-Jan-15 12:29 
QuestionWhat is the platform? Pin
RTFA12-Sep-14 14:19
memberRTFA12-Sep-14 14:19 
AnswerRe: What is the platform? Pin
Mohit Arora14-Sep-14 9:46
memberMohit Arora14-Sep-14 9:46 
GeneralMy vote of 1 Pin
Member 922181930-May-14 3:47
memberMember 922181930-May-14 3:47 
GeneralRe: My vote of 1 Pin
sasue113-Aug-14 8:03
membersasue113-Aug-14 8:03 
Questionsome questions of the service Pin
long050814-Apr-14 17:44
memberlong050814-Apr-14 17:44 
AnswerRe: some questions of the service Pin
Mohit Arora27-Aug-14 18:19
memberMohit Arora27-Aug-14 18:19 
GeneralMy vote of 5 Pin
AdityaDange18-Mar-14 23:32
memberAdityaDange18-Mar-14 23:32 
QuestionThanks! Pin
Doug Royer16-Jan-14 3:54
professionalDoug Royer16-Jan-14 3:54 
QuestionCannot install the service using the code Pin
ShresthaSika10-Dec-13 20:21
memberShresthaSika10-Dec-13 20:21 
AnswerRe: Cannot install the service using the code Pin
Mohit Arora23-Dec-13 21:44
memberMohit Arora23-Dec-13 21:44 
GeneralMy vote of 1 Pin
BBSS20125-Sep-13 0:40
memberBBSS20125-Sep-13 0:40 
QuestionOpenSCManager Failed Pin
Khurram Mirza3-Sep-13 15:38
memberKhurram Mirza3-Sep-13 15:38 
AnswerRe: OpenSCManager Failed Pin
Mohit Arora22-Dec-13 11:58
memberMohit Arora22-Dec-13 11:58 
GeneralMy vote of 5 Pin
gamesboy26-Aug-13 18:55
membergamesboy26-Aug-13 18:55 
GeneralMy vote of 5 Pin
Member 1016253318-Jul-13 19:25
memberMember 1016253318-Jul-13 19:25 
GeneralMy vote of 2 Pin
Cristian Amarie30-May-13 22:39
memberCristian Amarie30-May-13 22:39 
GeneralMy vote of 4 Pin
candy_yh30-May-13 20:57
membercandy_yh30-May-13 20:57 
QuestionHow do you use the debug ? Pin
Member 998626314-Apr-13 15:45
memberMember 998626314-Apr-13 15:45 
AnswerRe: How do you use the debug ? Pin
Mohit Arora23-Dec-13 21:50
memberMohit Arora23-Dec-13 21:50 
QuestionForgot CloseHandle(hThread). Pin
Member 99634613-Apr-13 14:56
memberMember 99634613-Apr-13 14:56 
AnswerRe: Forgot CloseHandle(hThread). Pin
Mohit Arora23-Dec-13 21:42
memberMohit Arora23-Dec-13 21:42 
QuestionI get Error 1053 when Start Pin
spyhunter8827-Jan-13 23:49
memberspyhunter8827-Jan-13 23:49 
I use your default code, build with DEBUG and RELEASE profile. Install by : sc "Sample Service" binPath= C:\SampleService.exe successfully.
But when run with sc start "Sample Service", I got error 1053 after 30s waiting. Also try with Services.msc and get the same result.
AnswerRe: I get Error 1053 when Start Pin
massimiliano7230-Apr-13 2:29
membermassimiliano7230-Apr-13 2:29 
GeneralRe: I get Error 1053 when Start Pin
yoka ko20-Nov-14 19:30
memberyoka ko20-Nov-14 19:30 
GeneralRe: I get Error 1053 when Start Pin
Eswar Yaganti31-Mar-15 0:58
memberEswar Yaganti31-Mar-15 0:58 
QuestionEasy Command Line Service Pin
Andy Bantly29-Nov-12 11:17
memberAndy Bantly29-Nov-12 11:17 

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.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.151125.3 | Last Updated 30 May 2013
Article Copyright 2012 by Mohit Arora
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid