Windows Service Information Component

This article is on a reusable window's service information component, which queries & retrieves the window's service information. Services executables don't have user interface and they run in background for long periods. These services can be automatically started when the computer boots, can be paused and restarted. There are two kinds of services, which runs in windows they are Device Driver services and Non Device Driver services, Apart from that service can be a interactive services and non-interactive service. An interactive service is a service that can interact with the input desktop.

In .Net framework library the System.ServiceProcess namespace provides classes that allow you to implement, install, and control Windows service applications. To implement a service we need to inherit from ServiceBase class.In this article we are not going implement a service we are going to develop a component which will retrieve & query the existing services. In order to proceed with this we will use ServiceController class (alias System.ServiceProcess.ServiceController). The ServiceController class enables you to connect to an existing service and manipulate it or get information about it.

So our component helps in administering the services running in local system.The ServiceBase class defines the processing a service performs when command occurs,the ServiceController is the agent that enable us to call those commands on the services.So we are going to create a component which is derived from System.ComponentModel.Component the default implementation of IComponent. IComponent serves as the base class for all components in the common language runtime and IComponent allows a component to keep track of design-time information, such as its container component or its name, or to access services that the designer may expose. . Component class is remotable and derives from MarshalByRefObject so which Enables access to objects across application domain boundaries in applications that support remoting.

Lets discuss first about ServiceInfo component, ServiceInfo Class is derived from Component class of .net frame work and this component will have read/write properties for getting/setting the Service information. So I have selected most important methods of ServiceController class methods to query the services.

Namespace : ServiceInfoLib

Class: ServiceInfo

Properties :1. DisplayType (get/set property)

Methods: 

  1. GetNonDDServicesDetails() (gets the Non Device Driver Service Details) 
  2. GetDDServicesDetails() (gets the Device Driver Service Details) 
  3. GetNonDDServicesStatus() (gets the Non Device Driver Service Status) 
  4. GetDDServicesStatus() (gets the  Device Driver Service Status) 
  5. FindService(string s) (Checks wether service exists or not)

    Most of the methods in ServiceInfo component returns as string array. Internally all the methods of the component will call the ServiceController methods.

Brief Description about the component methods:

  1. The GetNonDDServiceDetails() method of ServiceInfo component returns a list of all the Non Device Driver Service installed on your local system. It internally calls the SystemController.GetServices() method.It also uses the property called DisplayType in ServerInfo component where the property get/set the display name of the service.If it is set to display type 'D' then it gives the list of friendly display Name of the Services and if its set to 'S' then it gives the list of Service Name of the Services,internally it calls the ServiceController DisplayName and ServiceName properties.

  2. The GetDDServiceDetails() method of ServiceInfo component returns a list of all the Device Driver Service installed on your local system. It internally calls the SystemController.GetDevices() method.

  3. The GetNonDDServiceStatus() method of ServiceInfo component returns a list of all the Non Device Driver Service installed on your local system and there status which indicates whether the service is running, stopped, or paused, or whether a start, stop, pause, or continue command is pending. It internally calls the SystemController.GetServices() method and ServiceController.Status property which returns the ServiceControllerStatus class which indicates the status. In the component I used ResolveSrvStatus method to resolve the exact status.

  4. The GetDDServiceStatus() method of ServiceInfo component returns a list of all the  Device Driver Service installed on your local system and there status which indicates whether the service is running, stopped, or paused, or whether a start, stop, pause, or continue command is pending. It internally calls the SystemController.GetDevices() method and ServiceController.Status property which returns the ServiceControllerStatus class which indicates the status. In the component I used ResolveSrvStatus method to resolve the exact status.

  5. The FindService(string s) method of ServiceInfo component check for particular service exist in the local machine or not if its found it return a string saying 'Found' and it that particular service not exits then it returns 'Not Found'.

// SrvInfoLib.cs
// ServiceInfo component code in c#
using System;
using System.ComponentModel;
using System.ServiceProcess ;
namespace ServiceInfoLib
{
/// <summary>
/// ServiceInfo Class gets the windows service details.
/// </summary>
public class ServiceInfo: Component
{
private static char cDTyp='D'; // 'D' -> Display Name
// 'S' -> Service Name
public char DisplayType
{
set
{
cDTyp=
value;
}
get
{
return cDTyp;
}
}
public ServiceInfo(){}
//Retrieves a list of Non Device Driver Services
public string[] GetNonDDServicesDetails()
{
string[] s=null;
try
{
ServiceController[] srvC=ServiceController.GetServices();
s=
new string[srvC.Length];
for(int i=0;i<srvC.Length;i++)
{
if(cDTyp=='D')
s[i]=srvC[i].DisplayName;
else if(cDTyp=='S')
s[i]=srvC[i].ServiceName;
}
}
catch(Exception x){}
return s;
}
//Retrieves a list of Device Driver Services
public string[] GetDDServicesDetails()
{
string[] s=null;
try
{
ServiceController[] srvC=ServiceController.GetDevices();
s=
new string[srvC.Length];
for(int i=0;i<srvC.Length;i++)
{
if(cDTyp=='D')
s[i]=srvC[i].DisplayName;
else if(cDTyp=='S')
s[i]=srvC[i].ServiceName;
}
}
catch(Exception x){}
return s;
}
//Retrieves a list of Non Device Driver Services & status
public string[] GetNonDDServicesStatus()
{
string[] s=null;
try
{
ServiceController[] srvC=ServiceController.GetServices();
s=
new string[srvC.Length];
for(int i=0;i<srvC.Length;i++)
{
if(cDTyp=='D')
s[i]=srvC[i].DisplayName+"\t->" +ResolveSrvStatus(srvC[i].Status);
else if(cDTyp=='S')
s[i]=srvC[i].ServiceName+"\t->" +ResolveSrvStatus(srvC[i].Status);
}
}
catch(Exception x){}
return s;
}
//Retrieves a list of Device Driver Services & status
public string[] GetDDServicesStatus()
{
string[] s=null;
try
{
ServiceController[] srvC=ServiceController.GetDevices();
s=
new string[srvC.Length];
for(int i=0;i<srvC.Length;i++)
{
if(cDTyp=='D')
s[i]=srvC[i].DisplayName+"\t->" +ResolveSrvStatus(srvC[i].Status);
else if(cDTyp=='S')
s[i]=srvC[i].ServiceName+"\t->" +ResolveSrvStatus(srvC[i].Status);
}
}
catch(Exception x){}
return s;
}
//Checks for particular service exists or not
public string FindService(string s)
{
string s3=null;
try
{
ServiceController[] services;
services = ServiceController.GetServices();
for (int i = 0; i < services.Length; i++)
{
if(services[i].ServiceName==s)
{
s3="Found";
break;
}
}
}
catch(Exception x){}
if(s3==null)
return s3="Not Found";
else
return s3;
}
private string ResolveSrvStatus(ServiceControllerStatus sl)
{
string st="";
if(sl==ServiceControllerStatus.ContinuePending)
st="The service continue is pending.";
if(sl==ServiceControllerStatus.Paused)
st="The service is paused.";
if(sl==ServiceControllerStatus.PausePending)
st="The service pause is pending.";
if(sl==ServiceControllerStatus.Running)
st="The service is running.";
if(sl==ServiceControllerStatus.StartPending)
st="The service is starting.";
if(sl==ServiceControllerStatus.Stopped)
st="The service is stopped.";
if(sl==ServiceControllerStatus.StopPending)
st="The service is not running.";
return st;
}
}


Compile the above as component library to produce ServiceInfoLib.dll then one can call this component in different clients like WinForms, WebFroms or Console applications.I have used simple WinForm application to use this component. 

Servic1.jpg

Fig. Displays the Status of all Device Driver Services.

To use the component in the client add a reference in visual studio .Net and add using ServiceInfoLib; in the client code and  create a instance of the component ( ServiceInfo srv = new ServiceInfo() ) then use the methods of the component.

Following is the code snippet of button click events of the client application:

private void bNonDDSrvDet_Click(object sender, System.EventArgs e)
{
tDisp.Clear();
//text box
//Invokes ServiceInfo component Non Device Driver details method
string[] s=srv.GetNonDDServicesDetails();
for(int i=0;i<s.Length;i++)
{
tDisp.Text+=(s[i]+"\r\n");
}
}
private void bDDSrvDet_Click(object sender, System.EventArgs e)
{
tDisp.Clear();
//text box
//Invokes ServiceInfo component Device Driver details method
string[] s=srv.GetDDServicesDetails();
for(int i=0;i<s.Length;i++)
{
tDisp.Text+=(s[i]+"\r\n");
}
}
private void bNonDDSrvStat_Click(object sender, System.EventArgs e)
{
tDisp.Clear();
//text box
//Invokes ServiceInfo component Non Device Driver status method
string[] s=srv.GetNonDDServicesStatus();
for(int i=0;i<s.Length;i++)
{
tDisp.Text+=(s[i]+"\r\n");
}
}
private void bDDSrvStat_Click(object sender, System.EventArgs e)
{
tDisp.Clear();
//text box
//Invokes ServiceInfo component Device Driver status method
string[] s= srv.GetDDServicesStatus();
for(int i=0;i<s.Length;i++)
{
tDisp.Text+=(s[i]+"\r\n");
}
}
private void bDDSrvFind_Click(object sender, System.EventArgs e)
{
tDisp.Clear();
//text box
//check for Alerter service exists or not
tDisp.Text=srv.FindService("Alerter");
}
//setting the Display type property of ServiceInfo component
private void rbDispName_CheckedChanged(object sender, System.EventArgs e)
{
srv.DisplayType='D';
//friendly Display Name
}
//setting the Display type property of ServiceInfo component
private void rbSrvName_CheckedChanged(object sender, System.EventArgs e)
{
srv.DisplayType='S';
// Actual instance Service Name
}

Further reading

.Net  More information on .Net technologies