Introduction
This article is on a reusable windows service information component, which
queries & retrieves the window�s service information. Service executables don�t
have user interface and they run in the 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 the
service can be a interactive service or non-interactive service. An interactive
service is a service that can interact with the 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 to implement a service; but 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.
Details
So our component helps in administering the services running in the local system. The ServiceBase
class defines the processing, a service performs when
a 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
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 framework and this component will have read/write
properties for getting/setting the Service information. So I have selected important methods of ServiceController
class methods to query the services.
Namespace : ServiceInfoLib
Class: ServiceInfo
Properties :
-
DisplayType (get/set property)
Methods:
-
GetNonDDServicesDetails() (gets the Non Device
Driver Service Details)
-
GetDDServicesDetails() (gets the Device Driver
Service Details)
-
GetNonDDServicesStatus() (gets the Non Device Driver
Service Status)
-
GetDDServicesStatus() (gets the Device Driver
Service Status)
-
FindService(string s) (Checks whether service exists
or not)
|
Most of the methods in ServiceInfo
component returns a string
array. Internally
all the methods of the component will call the ServiceController
methods.
Brief Description about the component methods
- The
GetNonDDServiceDetails()
method of ServiceInfo
component returns a list of
all the Non Device Driver Services 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.
- 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.
- The
GetNonDDServiceStatus()
method of ServiceInfo
component returns a list of
all the Non Device Driver Service installed on your local system and their
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.
- The
GetDDServiceStatus()
method of ServiceInfo
component returns a list of
all the Device Driver Services installed on your local system and their 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.
- The
FindService(string s)
method of ServiceInfo
component
is to check whether a
particular service exists in the local machine or not; if its found it returns a
string
saying �Found� and if that particular service does not
exist, then it returns
�Not Found�
Source Code
using System;
using System.ComponentModel;
using System.ServiceProcess ;
namespace ServiceInfoLib
{
public class ServiceInfo: Component
{
private static char cDTyp='D';
public char DisplayType
{
set
{
cDTyp=value;
}
get
{
return cDTyp;
}
}
public ServiceInfo(){}
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;
}
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;
}
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;
}
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;
}
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 a component library to produce ServiceInfoLib.dll
and then one
can call this component in different clients like Windows Forms, Web Forms or Console
applications. I have used a simple Windows Forms application to use this component.
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()
) and 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();
string[] s=srv.GetNonDDServicesDetails();
for (inti=0; i<s.Length; i++)
{
tDisp.Text+=(s[i]+"\r\n");
}
}
private void bDDSrvDet_Click(object sender, System.EventArgs e)
{
tDisp.Clear();
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();
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();
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();
tDisp.Text=srv.FindService("Alerter");
}
private void rbDispName_CheckedChanged(object sender, System.EventArgs e)
{
srv.DisplayType='D';
}
private void rbSrvName_CheckedChanged(object sender, System.EventArgs e)
{
srv.DisplayType='S';
}