
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:
ServiceManager sm;
if(!sm.Initialize())
{
cout << "Cannot initialize." << endl;
getch();
return 1;
}
CServiceArray arr;
sm.GetServices(arr);
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();
}
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.