I've been working on a server monitoring Windows service recently - it's meant to keep an eye on our servers for various types of failures and, if possible, automatically recover from them. One of the failures our website experiences once in a while has to do with our forums. I integrated a third party forum package into our site so our stores have a place to post messages and talk with one another. Occasionally (and I have yet to reproduce the failure steps) it will fail, complaining that it can't find some configuration file. The quick fix is to reset IIS; usually I'll just remote into the server and do an IISRESET from the command prompt. I wanted my service to keep an eye out for this type of failure and automatically recycle IIS. Long term I'd love to track down this failure and fix it the proper way but in the meantime I just want to be able to recover gracefully.
I found the ServiceController class after a bit of digging and wrapped it up into two static methods I could call to reset IIS. I just had to figure out the name of the service I needed to refer to. The easiest way I found of finding this was to just cycle through the services and display their names. You could write a quick console app. to do this, but I just used LINQPad, switched it to C# Statements, added a reference to the System.ServiceProcess.dll (hit F4), then added the namespace System.ServiceProcess and ran the code.
As an aside: I can't say enough nice things about LINQPad - it makes it so nice to be able to test out new classes and ideas. Its name would lead you to believe it's only good for testing LINQ queries, but you can test out almost any .NET code you want. I spent the whopping $19 to upgrade to the full version, which adds Intellisense (the free version doesn't include that). I've added LINQPad to my "must have" .NET toolkit.
You might be wondering what the Dump() method does, since it's not part of the ServiceController class. LINQPad has a nice extension method named Dump() that makes it trivial to dump out the response from almost anything. My sample doesn't show it, but it even handles nested classes nicely. OK, enough fawning...
I ran this code which made it really easy to find the service names I was interested in. Once I had them I wrapped up a few of the services I wanted to be able to cycle in their own methods. I ended up wrapping the Start/Stop calls in a try/catch; it would throw an exception if I tried starting a service which was already running or stopping a service which had already stopped.
private void ResetIIS()
{
StopService("W3SVC", 10);
StartService("W3SVC", 15);
}
private void ResetStateServer()
StopService("aspnet_state", 15);
StartService("aspnet_state", 15);
public static void StopService(string serviceName, int timeoutSeconds)
using (ServiceController controller = new ServiceController(serviceName))
try
controller.Stop();
controller.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(timeoutSeconds));
catch (InvalidOperationException ex)
// Service may already be stopped
public static void StartService(string serviceName, int timeoutSeconds)
controller.Start();
controller.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(timeoutSeconds));
// Service may already be running
private void ListServices()
ServiceController[] services = ServiceController.GetServices();
foreach (ServiceController service in services)
string name = service.DisplayName + " : " + service.ServiceName;
Console.WriteLine(name);
//name.Dump();
Links:
http://www.linqpad.net
Remember Me
a@href@title, b, i, strike