C# Express - Create a Dummy or Placeholder Windows Service for Monitoring

Cre­at­ing my cus­tom ser­vice in Visu­al Stu­dio

The IT ecosys­tem is rich with net­work mon­i­tor­ing sys­tems (NMS). Each NMS has dif­fer­ent capa­bil­i­ties, costs, and pur­pos­es in life. It is com­mon­place for me to come into a busi­ness that has invest­ed in an NMS that does­n’t fit all their needs. You might ask, “What does this have to do with cre­at­ing a Win­dows ser­vice?” Here is the sce­nario that brought this up.

A client has a mon­i­tor­ing solu­tion for their Win­dows servers and some basic net­work up/down stats. Their inter­net con­nec­tion had been flaky for a month or two. As we worked with their ISP, their con­nec­tion con­tin­ued to stay up but laten­cy would spike and often drop pack­ets. The mon­i­tor­ing nev­er sees the link as down but the lev­el of ser­vice is degrad­ed and most­ly unus­able. The ISP can quick­ly reset the ports and fix the issue, but we want to know right when this hap­pens to min­i­mize down­time.

I set­up a pow­er­shell script with the help of the team at Com­put­er­Per­for­mance.  This script is pret­ty straight for­ward. It uses the Test-Con­nec­tion cmdlet and aver­ages the laten­cy to a remote host.

# Gets the average latency between you and $Server
# Using IP Addresses is recommended
$Server = "8.8.8.8"
$PingServer = Test-Connection -count 20 $Server
$Avg = ($PingServer | Measure-Object ResponseTime -average)
$Calc = [System.Math]::Round($Avg.average)
If ($Calc -gt 100 -Or $Calc -eq 0) {stop-service MyService} Else {start-service MyService}

Now, for the tricky part. How do I cre­ate a ser­vice that I can start and stop with­out actu­al­ly impact­ing the under­ly­ing OS? I won’t go into the code too much but I have includ­ed the exam­ple C# source files in a zip at the bot­tom. I got this code from a MSDN social forum post.

To imple­ment this, first make sure you read the forum post. You will need Visu­al Stu­dio 2010 C# Express. Cre­ate a Win­dows Form Appli­ca­tion and include ref­er­ences (Project --> Add Ref­er­ences --> .NET) to System.Configuration.Install and System.ServiceProcess. You will need three files in your project: MyService.cs, MyServiceInstaller.cs and Program.cs. These are includ­ed in a zip at the end of this arti­cle (I also includ­ed the exe­cutable from the code if you want to test it out). You real­ly only need to edit the MyService.cs and MyServiceInstaller.cs to match the Ser­vice’s pur­pose in life (and write use­ful event log entries). Once that is done, build the pro­gram. You will get an error on build about a “Win­dows Ser­vice Start Fail­ure” as shown below. (Any devel­op­ers out there know how to make this build w/o throw­ing the obvi­ous error?) Just ignore the error and grab the exe­cutable from the Debug fold­er of the project. Place the exe­cutable some­where safe (I use %windir%SysWOW64 in my exam­ple below).

Next, we need to install the ser­vice. You can install the ser­vice using the SC com­mand in Win­dows. In this exam­ple, I used the name “lat­test” as the ser­vice name and defined the dis­play name as well. You can find more infor­ma­tion on the SC.exe com­mand here. Note: those spaces after the equals (=) sign are required when using the SC com­mand.  Here is the code I used to install this ser­vice on Serv­er 2008 R2:

sc create lattest binpath= "C:WindowsSysWOW64MyService.exe" displayname= "Latency Test" start= auto

At this point, your script can be set­up to run as a sched­uled task to start or stop the ser­vice depend­ing on the con­di­tions you set. You can point your NMS to mon­i­tor the ser­vice and you can sleep peace­ful­ly at night know­ing you are proac­tive­ly mon­i­tor­ing the issue.

If this is tem­po­rary in nature and you want to remove the ser­vice, just remove it from your NMS, delete the ser­vice and exe­cutable and remove your sched­uled task. The ser­vice can be removed by run­ning:

sc delete lattest

Here is the code from the Visu­al Stu­dio Project: MyService.zip