.NET 3.5, Download, WCF

How-to: Get status from a windows service?

I was asked: “How can I call into a Windows Service to get it’s status?”


A little more background said that status was to be retrieved by clients (a website) on the same machine.


My response was to use WCF with the NetNamedPipeBinding. Since the recipient of my response, by his own accord, was unaccustomed to WCF, I decided to write up a small app that showed the concept.


The key thing here is that service expose an endpoint at an address that looks like this: net.pipe://localhost/ServiceMonitoringEndpoints/<name_of_service>. Name of service will be the same name as the ServiceName property of the ServiceInstaller component. This enables us to et the status of an arbitrary service just by knowing its name. First we look at the status through ServiceController and then, if the service is running, we call the WCF service to get the actual status, in this case in the form of a string. Pretty simple, wrapped up in a Library component ready to be used by both Windows Service servers and their clients. The Windows Service server is configured through its config file in my sample, but that’s something you can alter should that be one of your requirements.


Basically the server configuration is (mex of course not really necessary):

<services>
  <service behaviorConfiguration=“includeExBehavior”
      name=“SharedMonitoringUtilityLibrary.MonitoringService”>
    <endpoint address=“” binding=“netNamedPipeBinding”
              contract=“SharedMonitoringUtilityLibrary.IMonitoringService” />
    <endpoint address=“mex” binding=“mexNamedPipeBinding”
              contract=“IMetadataExchange” />
  </service>
</services>

and the it uses one of ServiceHosts constructors to supply that takes type and address:

protected override void OnStart(string[] args)
{
    host = new ServiceHost(typeof(SharedMonitoringUtilityLibrary.MonitoringService),
        new Uri(“net.pipe://localhost/ServiceMonitoringEndpoints/MonitorMeWithWCFService_Service1/“));
    host.Open();
    MonitoringService.Status = “Started at ” + DateTime.Now.ToString();
}
protected override void OnStop()
{
    if (host != null)
        host.Close();
}

as you can see from the code above, I’m simply using a static method to supply the status to the running WCF Service. This particular point of interaction wasn’t my primary point of this post or code. A better option could be getting an instance of the host from the other direction using an overloaded ServiceHost and Get the host using OperationContext.InstanceContext.Host.. Another option might even be where the server is a client to it’s own service, using a set method to set the status. What you don’t want to do is make the service hostdependent. Just be aware that my choice above is clearly limiting, and that you have plenty of other options.


The client is dynamically configured to look for and call the service using the following method:

Binding binding = new NetNamedPipeBinding();
EndpointAddress endpoint = new EndpointAddress(
    string.Format(@”net.pipe://localhost/ServiceMonitoringEndpoints/{0}/“, serviceName));
MonitoringServiceClient client = new MonitoringServiceClient(binding, endpoint);
statusInfo = client.GetStatus();

Although it’s surrounded by other things as well in the actual sample code, like the call to ServiceController.


Here is the sample code.


It contains three projects. The Windows Service Server, the library and a simple console client. Compile the sample code, install the service using installutil and run the client. Now that you’ve validated it and it’s running you can begin expanding it.


Additional Resources:
Hosting WCF Service in Windows Service screencast
Hosting and consuming WCF services
NamedPipe activation

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s