Writing a Service Program


Desktop-as-a-Service Designed for Any Cloud ? Nutanix Frame

Environment: Visual C++6 SP5, Windows 2000/XP


A few weeks ago, I was trying to make my own server application into a service without much knowledge about how to do it. Now, I know more about services and would like to share my knowledge in this article.

Services are processes that can be auto started when the system boots, and can be left them running while the system is on. For example, system services are services such as an Event log that logs messages issued by Windows-based programs and components to be viewed in Event Viewer. Services are similar to UNIX's daemons.

A Windows service applet can be found in Control Panel > Administrator Tools > Services. Any new services installation creates an entry in this applet and in the Registry (HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services), so that the system knows about it each time it boots.

Every service must be able to respond to a set of standard events that the services applet can pass to it. These events are shown in the window service as buttons:

  • START: Starts the service if it is a manual start service or it is stopped.
  • STOP: Stops the service.
  • PAUSE: Suspends the service temporarily.
  • CONTINUE: Resumes the suspended service.

All services are managed under a system called the Service Control Manager. It maintains the list of known services in the Registry and starts them at boot time or when requested.

A program that acts as a service is a normal EXE file, but it must meet special requirements so that it interfaces properly with the Service Control Manager (SCM). The requirements follow:

  1. EXE must have a normal main or WinMain function. Call the StartServiceCrtlDispatcher function to register the EXE with the SCM and give the SCM a pointer to the ServiceMain function.
  2. void main(int argc, char *argv[])
      SERVICE_TABLE_ENTRY serviceTable[] =
        { ServiceName, (LPSERVICE_MAIN_FUNCTION) ServiceMain},
          { NULL, NULL}
      BOOL success;
      if(argc == 2)
        //..check arguments
        //register with SCM
        success = StartServiceCtrlDispatcher(serviceTable);
        if (!success)
  3. SCM will call the ServiceMain function when it wants to start the service. The ServiceMain should immediately call the RegisterServiceCtrlHandler function to register a Handler function with SCM.
  4. void ServiceMain(DWORD argc, LPTSTR *argv)
      BOOL success;
      //immediately call registration function
      serviceStatusHandle =
      //notify SCM
      //create termination event
      terminateEvent = CreateEvent (0, TRUE, FALSE, 0);
      //notify SCM
      //check for startup parameter
      //start service
      //notify SCM service is runnning
      SendStatusToSCM(SERVICE_RUNNING, NO_ERROR, 0 , 0, 0);
      //wait for stop signal and then terminate
      WaitForSingleObject(terminateEvent, INFINITE);
  5. The Handler function contains switch statements that parse control requests received from the SCM.
  6. void ServiceCtrlHandler(DWORD controlCode)
      DWORD currentState = 0;
      BOOL success;
        // START = ServiceMain()
        // STOP
          currentState = SERVICE_STOP_PENDING;
          //notify SCM
          //stop service
        // PAUSE
          if (runningService && !pauseService)
            //notify SCM
            success = SendStatusToSCM(
            currentState = SERVICE_PAUSED;
        // RESUME
          if (runningService && pauseService)
            //notify SCM
            success = SendStatusToSCM(
            currentState = SERVICE_RUNNING;
        // UPDATE
          //update status out of switch()
          //do nothing
      //notify SCM current state
      SendStatusToSCM(currentState, NO_ERROR, 0, 0, 0);
  7. When you create an EXE that contains that main, ServiceMain, and Handler functions, as well as a function that contains the thread for the service itself, you will have a complete service program.

Template for the Service Program

The accompanying .cpp file is a template for the service program, service control program (RUN, STOP, PAUSE, CONTINUE), and also the configuration program in the sense that it can install or remove the EXE itself using command.


  1. Add service.cpp to the project workspace.
  2. Change the ServiceName under the global variable to the desired name.
  3. Add your function into ServiceThread().
  4. DONE!

To Install

  1. Use command prompt.
  2. Locate the EXE.
  3. Type <programname> -i to install
    Type <programname> -u to uninstall
    Type <programname> -r to run
    Type <programname> -s to stop
    Type <programname> -p to pause
    Type <programname> -c to continue
    Type <programname> help


Download source - 6 Kb


  • problem in pause

    Posted by samira on 08/14/2012 10:18am

    hi thanks for ur nice post! ive developed a service like u but ihave a problem in pause the service! my service work when i pause it and its get changed to pause but it dosnt sleep! it mean the code in its service main continiue running!!!! what can i do because this section run in operating system side!!!

  • invalid current state 0

    Posted by chuck59 on 09/20/2005 03:58pm

    I modified your code to integrate it into my application. Now, I've a DLL which fetches and displays status of all services. Every other service reports their correct current except this one; following was logged into the Event Manager...
    The  service has reported an invalid current state 0.
    Event Type:	Error
    Event Source:	Service Control Manager
    Event Category:	None
    Event ID:	7016
    Date:		20-Sep-05
    Time:		17:40:26
    User:		N/A
    The PServ3 service has reported an invalid current state 0.
    For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.
    Waiting for your reply.

  • Very Good

    Posted by anantwakode on 09/19/2005 12:22pm

    Its nice artical for begineer to understand Service app

  • How to build a project?

    Posted by Tinoky on 05/09/2005 11:09pm

    It's exactly what I'm searching for. But since I never built any project without using the Application Wizard, I don't know how to build this service. Can anybody tell me more (which kind of project, can it be an MFC, etc....)

  • I enjoyed the article

    Posted by Legacy on 09/26/2003 07:00am

    Originally posted by: Nick

    There might be dozens of other articles like this, but I had trouble finding one! Maybe I'm using search engine wrong, but even now that I know this article is here, this is the only thing I could find:

    <i><b>System - Table of Contents</b>
    [ more results like this ]
    Find the lowest price for a variety of products: Featured Categories: CodeGuru Sites Interact Of Interest Article Sections Other Section C++ COM-based Technologies Controls Data Frameworks Graphics & Multimedia Internet & Networking Miscellaneous Visual Studio Windows Programming Windows & Dialogs internet.commerce

    Relevance: 97%

    That's the search engine's description of this article. Gee, how am I supposed to figure that one out??

  • Beginner question, thanks for the good example

    Posted by Legacy on 08/15/2003 07:00am

    Originally posted by: TimC

    The code in this article works well in it's own MS Visual C++ 6 (new .NET version in the mail) but, when I paste the exact same code into my much bigger project (none of my code getting involved) the call to StartServiceCtrlDispatcher() never results in ServiceMain() getting called. I've fixed this kind of problem in the past by trashing my project and starting fresh in a new one, but what a pain. Any ideas?

    As it turns out, I've experimented with a rather large number of sample Windows service programs (trying to see why I have the above problem.) This one is easily one of the best: simple yet the most complete I've found. I could use it as an example of the right way to write sample programs in general. With luck we'll see more like this one.

  • Obvoius

    Posted by Legacy on 08/11/2003 07:00am

    Originally posted by: dakkk

    Hy CodeGuru! You are becoming the laughing stock of everyone that had something to do with CodeGuru not by publishing such an article but rather by allowing some "Neanderthals" to post improper comments.

    No offense but there are a lot of GREEN programmers that might have read the article and found it useful. For all the others just one thing: Did someone put a gun to your head and MADE you read it?? Don't think so ... So it's simple: If you don't find it interesting then don't read it.

    From experience I can say that I would rather look at the way someone implemented a known concept than look in MSDN. Sometimes you may even find some new simple ideas that would help, even if it's a ****o world app...

    It is here that I first found topics about flicker free drawing (things I would never find in MSDN :) for that matter) and they were stated in a HW app.

    So if anyone at CodeGuru has any dignity left then it should "moderate" this pathetic excuse for a "discussion list"

  • Codeguru: Please *MODERATE" this list!

    Posted by Legacy on 08/09/2003 07:00am

    Originally posted by: Rodrigo Madera

    This isn't right for a coding page. Administrators *must* edit this nonsense comments.

    It hurts Codeguru's image to let un-supervised comments like these.

    Hire someone to do the job. (How about Brian?)

  • Good Attempt

    Posted by Legacy on 08/08/2003 07:00am

    Originally posted by: Bill Gates+++

    I am surprized at the negative comments for this article. Guys if you dont like the article, why to read it all. Read something that you think is new. Ignore known articles on the known subject.

  • Last visit

    Posted by Legacy on 08/07/2003 07:00am

    Originally posted by: Mark

    This just about does it.
    At one time this was the prime-programming site and I came every day to read the articles. Yes, some were a little dull or simplistic but the fact is that people have gone to the time and trouble to produce them. No one is forcing anyone else to read the articles or appraise the submissions.
    However, what I do object to is comments that are rude and profane for no other reason than that they can be. And I don't even blame the childish morons who are submitting these comments. I blame the web master for not taking responsibility to ensure that what goes up is, at the very least, sensible and polite criticism. It can still be harsh and pointed but the use of bad language and personal criticism is uncalled for and shows that the submitter has a) poor command of the language and b) cannot control their childish tantrums.
    I'm off to Code Project where all the grown-ups live.

  • Loading, Please Wait ...

  • You must have javascript enabled in order to post comments.

Leave a Comment
  • Your email address will not be published. All fields are required.

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date