Windows service monitoring application
Today we are going to create a windows service monitoring application in C#.Net.
A windows service is an application which runs in background without a GUI. They are used to monitor various activities such as database operations and message queues. For an example a windows service may periodically monitor a message queue and if new entries are added to the queue, the service will treat them. By using Visual Studio, creation and deployment of windows services is extremely easy. After deployment of the service, the services window comes under Administrative tools can be used to start, stop, pause and resume the service.
Today we are not going to discuss about creation of windows services. We focus on creating an application for monitoring any windows service. This includes both local and remote services! This application will reside in the system tray, connects to any service in the network and displays the current status of the service. Let’s create the application.
ServiceController class found in System.ServiceProcess namespace can be used to monitor services. We can create an instance of this class and get the current status from the Status property. The code for this is as follows;
System.ServiceProcess.ServiceController sc = new ServiceController(service, machine);
ServiceControllerStatus newStatus = sc.Status;
Here, service variable contains a service name and the machine variable contains a machine name.
We have to create a method which polls the status periodically without stopping. For that, a while (true)construct is the way to go. Since we should be able to connect to multiple services, we keep the settings in a text file to change/read them at will. Also this service monitoring section has to be executed in a separate thread other than the main UI thread because a context menu would be accompanied with the application and it will work as part of the main thread. The method having this code would be as follows;
public void monitorStatusChange()
{
try
{
while (true)
{
if (Thread.CurrentThread.ThreadState == ThreadState.Running)
{
Thread.Sleep(Int32.Parse(System.Configuration.ConfigurationManager.AppSettings["ThreadSleepTime"]));
}
lock (objLock)
{
//Read settings from file
FileStream stream = new FileStream(Application.StartupPath + “/settings.txt”, FileMode.OpenOrCreate);
StreamReader reader = new StreamReader(stream);
string machine, service, userName, password;
machine = reader.ReadLine();
service = reader.ReadLine();
userName = reader.ReadLine();
password = reader.ReadLine();
reader.Close();
stream.Close();
System.ServiceProcess.ServiceController sc = new ServiceController(service, machine);
ServiceControllerStatus newStatus = sc.Status;
if (currentStatus != newStatus)
{
if (newStatus == ServiceControllerStatus.Running)
{
notifyIcon1.Icon = new Icon(Application.StartupPath + “/images/Started.ico”);
}
if (newStatus == ServiceControllerStatus.Paused)
{
notifyIcon1.Icon = new Icon(Application.StartupPath + “/images/Paused.ico”);
}
if (newStatus == ServiceControllerStatus.Stopped)
{
notifyIcon1.Icon = new Icon(Application.StartupPath + “/images/Stopped.ico”);
}
}
currentStatus = newStatus;
}
}
}
catch (Exception ex)
{
notifyIcon1.Icon = new Icon(Application.StartupPath + “/images/Error.ico”);
currentStatus = new ServiceControllerStatus();
//lock (objLockRestart)
//{
// restartToolStripMenuItem.Enabled = true;
//}
}
}
When you go through the above piece of code, you may be confused by the lock keyword and the notifyIcon1. The lock keyword is used in order to access shared resources in a thread safe manner. Here the settings.txt file may be accessed by this monitorStatusChange() method and the UI thread simultaneously. For an instance, the context menu will have a menu item called “Manage settings” and by clicking on that, a form will be displayed to edit the settings. At the time of saving the modifications by this form, if the monitoring thread tries to read settings from the same file, an IOException will be raised as follows,
“The process cannot access the file because it is being used by another process”
Notify icon is the icon which is visible in the system tray. As per the above method, we are changing the icon depending on the current status of the service.
I hope you are clear with the monitoring part. But you may not have written an application which resides in the system tray and below steps are given for creating such an app.
1. Add a windows forms application project for the solution.
2. To the default page, drag a Notify control and a contextmenustrip control.
3. Assign the contextmenustrip control to the Notify icon’s ContextMenuStrip property.
4. Make Notify control’s Visible property to true.
5. Select an icon for the Notify control’s icon property.
6. Change form’s Opacity to 0%.
7. Select form’s ShowInTaskBar property as false.
8. Select form’s FormBorderStyle property as fixedtoolwindow.
When running the application, you would see it as in the following image. Look at the settings window and the context menu above the System Tray icon (The particular service is in the stopped state here).

I hope you have got a clear idea about this application. The source code for the application can be downloaded from the link at the top. Remember I have used third party GUI controls for this application called DotNetBar controls. This is my first ever blog entry and you are warmly welcome for putting comments here.
I will be writing another blog post very soon for enhancing this application in order to control the service both locally and remotely.
Cheers!!!!