Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C++

An easy way to enumerate, start, and stop services

2.76/5 (9 votes)
29 Jan 2007CPOL1 min read 1   694  
An article on controlling services in WinNT or higher.

Sample Image - Service_manager.jpg

Introduction

In my recent project, I had to list all the services in the system and start/stop them when certain conditions occurred. As I was completely unfamiliar with the Service API, I started digging in MSDN, and soon found out that the task at hand was in fact extremely simple. This article describes the two small classes that I wrote to wrap the API for enumerating, starting, and stopping services, as well as getting their status.

Using the code

The code contains two classes: ServiceManager and Service (the latter being actually a structure). ServiceManager can be used to retrieve an array of Service objects, each containing detailed information on the service in question. The ServiceManager class also allows to start and stop services by their name.

The code in these classes consumes a bit more memory than pure API calls do, but that's a fair price for a convenient interface.

Below is the code you could write to use the classes:

//Step 1: Create a ServiceManager instance and Initialize it.
//        If Initialize() returns false,
//        you probably don't have the Administrator
//        privileges to manage services

ServiceManager sm;
if(!sm.Initialize())
{
    cout << "Cannot initialize." << endl;
    getch();
    return 1;
}

//Step 2: Get the list of services (both running and stopped/disabled)

CServiceArray arr;
sm.GetServices(arr);

//Step 3: Enumerate them

cout << "Services Running:" << "-------------------" << endl;
for(int i=0; i<<arr.GetSize(); ++i)
{
    CString n1 = arr[i].GetName();
    n1.CharToOem();
    CString n2 = arr[i].GetDisplayName();
    n2.CharToOem();

    cout << n1 << " (" << n2 << ")" << endl;
    cout << "Status: " 
         << ((arr[i].GetStatus()==Active)?("Active"):("Inactive")) 
         << endl;
    cout << "Process ID: " << arr[i].GetProcessID() << endl;
    cout << endl;

    if(!(i%5) && i!=0)
        getch();
}

//Step 4: If you so desire, you may stop or run any service like this

sm.StartService("MySQL");
sm.StopService("MySQL");

Points of Interest

ServiceManager fails to initialize if you don't have Administrator privileges, which is not entirely correct because normally, you don't need those privileges to list services, only to start or stop them. While I realize this is a problem, I figured most people (myself included) would only really need to get the list of services when they intend to manage them.

Disclaimer

Use this code at your own risk. I had to say it, but then again there doesn't seem to be anything risky about it.

Happy coding!

Revision History

  • January 31, 2007 - Fixed the project file to default to Multibyte Character Set build.
  • January 30, 2007 - Originally posted.

License

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