8 out of 19 rated this helpful - Rate this topic

How to: Host a WCF Service in a Managed Windows Service

This topic outlines the basic steps required to create a Windows Communication Foundation (WCF) service that is hosted by a Windows Service. The scenario is enabled by the managed Windows service hosting option that is a long-running WCF service hosted outside of Internet Information Services (IIS) in a secure environment that is not message activated. The lifetime of the service is controlled instead by the operating system. This hosting option is available in all versions of Windows.

Windows services can be managed with the Microsoft.ManagementConsole.SnapIn in Microsoft Management Console (MMC) and can be configured to start up automatically when the system boots up. This hosting option consists of registering the application domain (AppDomain) that hosts a WCF service as a managed Windows service so that the process lifetime of the service is controlled by the Service Control Manager (SCM) for Windows services.

The service code includes a service implementation of the service contract, a Windows Service class, and an installer class. The service implementation class, CalculatorService, is a WCF service. The CalculatorWindowsService is a Windows service. To qualify as a Windows service, the class inherits from ServiceBase and implements the OnStart and OnStop methods. In OnStart, a ServiceHost is created for the CalculatorService type and opened. In OnStop, the service is stopped and disposed. The host is also responsible for providing a base address to the service host, which has been configured in application settings. The installer class, which inherits from Installer, allows the program to be installed as a Windows service by the Installutil.exe tool.

Construct the service and provide the hosting code

  1. Create a new Visual Studio Console Application project called "Service".

  2. Rename Program.cs to Service.cs.

  3. Change the namespace to Microsoft.ServiceModel.Samples.

  4. Add references to the following assemblies.

    • System.ServiceModel.dll

    • System.ServiceProcess.dll

    • System.Configuration.Install.dll

  5. Add the following using statements to Service.cs.

    using System.ComponentModel;
    using System.ServiceModel;
    using System.ServiceProcess;
    using System.Configuration;
    using System.Configuration.Install;
    
    
  6. Define the ICalculator service contract as shown in the following code.

    // Define a service contract.
    [ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
    public interface ICalculator
    {
        [OperationContract]
        double Add(double n1, double n2);
        [OperationContract]
        double Subtract(double n1, double n2);
        [OperationContract]
        double Multiply(double n1, double n2);
        [OperationContract]
        double Divide(double n1, double n2);
    }
    
    
  7. Implement the service contract in a class called CalculatorService as shown in the following code.

    // Implement the ICalculator service contract in a service class.
    public class CalculatorService : ICalculator
    {
        // Implement the ICalculator methods.
        public double Add(double n1, double n2)
        {
            double result = n1 + n2;
            return result;
        }
    
        public double Subtract(double n1, double n2)
        {
            double result = n1 - n2;
            return result;
        }
    
        public double Multiply(double n1, double n2)
        {
            double result = n1 * n2;
            return result;
        }
    
        public double Divide(double n1, double n2)
        {
            double result = n1 / n2;
            return result;
        }
    }
    
    
  8. Create a new class called CalculatorWindowsService that inherits from the ServiceBase class. Add a local variable called serviceHost to reference the ServiceHost instance. Define the Main method that calls ServiceBase.Run(new CalculatorWindowsService)

    public class CalculatorWindowsService : ServiceBase
    {
        public ServiceHost serviceHost = null;
        public CalculatorWindowsService()
        {
            // Name the Windows Service
            ServiceName = "WCFWindowsServiceSample";
        }
    
        public static void Main()
        {
            ServiceBase.Run(new CalculatorWindowsService());
        }
    
    
  9. Override the OnStart method by creating and opening a new ServiceHost instance as shown in the following code.

    // Start the Windows service.
    protected override void OnStart(string[] args)
    {
        if (serviceHost != null)
        {
            serviceHost.Close();
        }
    
        // Create a ServiceHost for the CalculatorService type and 
        // provide the base address.
        serviceHost = new ServiceHost(typeof(CalculatorService));
    
        // Open the ServiceHostBase to create listeners and start 
        // listening for messages.
        serviceHost.Open();
    }
    
    
  10. Override the OnStop method closing the ServiceHost as shown in the following code.

    protected override void OnStop()
    {
        if (serviceHost != null)
        {
            serviceHost.Close();
            serviceHost = null;
        }
    }
    
    
  11. Create a new class called ProjectInstaller that inherits from Installer and that is marked with the RunInstallerAttribute set to true. This allows the Windows service to be installed by the Installutil.exe tool.

    // Provide the ProjectInstaller class which allows 
    // the service to be installed by the Installutil.exe tool
    [RunInstaller(true)]
    public class ProjectInstaller : Installer
    {
        private ServiceProcessInstaller process;
        private ServiceInstaller service;
    
        public ProjectInstaller()
        {
            process = new ServiceProcessInstaller();
            process.Account = ServiceAccount.LocalSystem;
            service = new ServiceInstaller();
            service.ServiceName = "WCFWindowsServiceSample";
            Installers.Add(process);
            Installers.Add(service);
        }
    }
    
    
  12. Remove the Service class that was generated when you created the project.

  13. Add an application configuration file to the project. Replace the contents of the file with the following configuration XML.

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <system.serviceModel>    <services>
          <!-- This section is optional with the new configuration model
               introduced in .NET Framework 4. -->
          <service name="Microsoft.ServiceModel.Samples.CalculatorService"
                   behaviorConfiguration="CalculatorServiceBehavior">
            <host>
              <baseAddresses>
                <add baseAddress="http://localhost:8000/ServiceModelSamples/service"/>
              </baseAddresses>
            </host>
            <!-- this endpoint is exposed at the base address provided by host: http://localhost:8000/ServiceModelSamples/service  -->
            <endpoint address=""
                      binding="wsHttpBinding"
                      contract="Microsoft.ServiceModel.Samples.ICalculator" />
            <!-- the mex endpoint is exposed at http://localhost:8000/ServiceModelSamples/service/mex -->
            <endpoint address="mex"
                      binding="mexHttpBinding"
                      contract="IMetadataExchange" />
          </service>
        </services>
        <behaviors>
          <serviceBehaviors>
            <behavior name="CalculatorServiceBehavior">
              <serviceMetadata httpGetEnabled="true"/>
              <serviceDebug includeExceptionDetailInFaults="False"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
      </system.serviceModel>
    </configuration>
    

    Right click the App.config file in the Solution Explorer and select Properties. Under Copy to Output Directory select Copy if Newer.

    This example explicitly specifies endpoints in the configuration file. If you do not add any endpoints to the service, the runtime adds default endpoints for you. In this example, because the service has a ServiceMetadataBehavior set to true, your service also has publishing metadata enabled. For more information aboutdefault endpoints, bindings, and behaviors, see Simplified Configuration and Simplified Configuration for WCF Services.

Install and run the service

  1. Build the solution to create the Service.exe executable.

  2. Open the Visual Studio 2010 command prompt and navigate to the project directory. Type installutil bin\service.exe at the command prompt to install the Windows service.

    ms733069.note(en-us,VS.100).gifNote:
    If you do not use the Visual Studio 2010 command prompt, make sure that the %WinDir%\Microsoft.NET\Framework\v4.0.<current version> directory is in the system path.

    Type services.msc at the command prompt to access the Service Control Manager (SCM). The Windows service should appear in Services as "WCFWindowsServiceSample". The WCF service can only respond to clients if the Windows service is running. To start the service, right-click it in the SCM and select "Start", or type net start WCFWindowsServiceSample at the command prompt.

  3. If you make changes to the service, you must first stop it and uninstall it. To stop the service, right-click the service in the SCM and select "Stop", or type net stop WCFWindowsServiceSample at the command prompt. Note that if you stop the Windows service and then run a client, an EndpointNotFoundException exception occurs when a client attempts to access the service. To uninstall the Windows service type installutil /u bin\service.exe at the command prompt.

Example

The following is a complete listing of the code used by this topic.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.ComponentModel;
using System.ServiceModel;
using System.ServiceProcess;
using System.Configuration;
using System.Configuration.Install;

namespace Microsoft.ServiceModel.Samples
{
    // Define a service contract.
    [ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
    public interface ICalculator
    {
        [OperationContract]
        double Add(double n1, double n2);
        [OperationContract]
        double Subtract(double n1, double n2);
        [OperationContract]
        double Multiply(double n1, double n2);
        [OperationContract]
        double Divide(double n1, double n2);
    }

    // Implement the ICalculator service contract in a service class.
    public class CalculatorService : ICalculator
    {
        // Implement the ICalculator methods.
        public double Add(double n1, double n2)
        {
            double result = n1 + n2;
            return result;
        }

        public double Subtract(double n1, double n2)
        {
            double result = n1 - n2;
            return result;
        }

        public double Multiply(double n1, double n2)
        {
            double result = n1 * n2;
            return result;
        }

        public double Divide(double n1, double n2)
        {
            double result = n1 / n2;
            return result;
        }
    }

    public class CalculatorWindowsService : ServiceBase
    {
        public ServiceHost serviceHost = null;
        public CalculatorWindowsService()
        {
            // Name the Windows Service
            ServiceName = "WCFWindowsServiceSample";
        }

        public static void Main()
        {
            ServiceBase.Run(new CalculatorWindowsService());
        }

        // Start the Windows service.
        protected override void OnStart(string[] args)
        {
            if (serviceHost != null)
            {
                serviceHost.Close();
            }

            // Create a ServiceHost for the CalculatorService type and 
            // provide the base address.
            serviceHost = new ServiceHost(typeof(CalculatorService));

            // Open the ServiceHostBase to create listeners and start 
            // listening for messages.
            serviceHost.Open();
        }

        protected override void OnStop()
        {
            if (serviceHost != null)
            {
                serviceHost.Close();
                serviceHost = null;
            }
        }
    }

    // Provide the ProjectInstaller class which allows 
    // the service to be installed by the Installutil.exe tool
    [RunInstaller(true)]
    public class ProjectInstaller : Installer
    {
        private ServiceProcessInstaller process;
        private ServiceInstaller service;

        public ProjectInstaller()
        {
            process = new ServiceProcessInstaller();
            process.Account = ServiceAccount.LocalSystem;
            service = new ServiceInstaller();
            service.ServiceName = "WCFWindowsServiceSample";
            Installers.Add(process);
            Installers.Add(service);
        }
    }
}

Like the "Self-Hosting" option, the Windows service hosting environment requires that some hosting code be written as part of the application. The service is implemented as a console application and contains its own hosting code. In other hosting environments, such as Windows Process Activation Service (WAS) hosting in Internet Information Services (IIS), it is not necessary for developers to write hosting code.

See Also

Did you find this helpful?
(1500 characters remaining)
Community Content Add
Annotations FAQ
Step 12: Remove the Service class
Step 12 states the following:
Remove the Service class that was generated when you created the project.

I understood, that all the code should go to Service class. If I delete it, what will remain?
in the works
I complained about this article before but it seems like adding few references solved the issue.
Working Sample
For all developers here who aren't able to achieve the sample mentioned running. Please use the sample I have uploaded in http://cid-41ce408c159c69ea.office.live.com/self.aspx/Public/WindowsServiceWCF.zip

Also please note that you might need to add a Pre-Build command in to the project as Copy $(ProjectDir)App.config $(TargetDir)$(TargetFileName).config This will copy the App.Config to ProjectFileName.exe.config to the output folder.

*** YOU ARE A LEGEND DUDE THANKYOU VERY MUCH EVERYTHING WORKS PERFECTLY *** - Josh
Go to event log if problems arise
For those who are getting messages like "service started then stopped": Go to windows protocols > application (eventvwr.exe), the errors should be specified there and hopefully point you to the solution. Most times there will be something amiss with the app.config and name matching.
It worked for me.
  • After following the instructions, I was able to get this how to work. There were just a few bits that I needed to add.
  • Run the Visual Studio 2010 Command Prompt as an administrator.
  • Do this by right clicking on the VS 2010 Command Prompt and then choosing Run as Administrator. 
  • Run installutil bin\debug\service.exe instead of bin\service.exe because my service.exe went into the bin\debug folder.
  • By making these changes, the how to worked for me with .NET 4.0

     

Namespace:Microsoft.ServiceModel.Samples
Dear Author/All, $0$0 $0 $0 $0 $0Why is it necessary to change the namespace to: Microsoft.ServiceModel.Samples?$0 $0Why are we adding namespace to attribute ServiceContract[Namespace( = "http://Microsoft.ServiceModel.Samples"$0 )]$0 $0 $0Please guide me....$0 $0 $0$0 $0 $0Regards,$0 $0Priyank$0 $0$0 $0 $0
Not so basic WCF
I object to the RTM attitude of the comment previous to this one. This is supposed to be a beginner level tutorial. Therefore, you can't really expect any familiarity with .NET (or even C# probably). I've been working in .NET for years, and I still stumbled on the fact that my namespace didn't match the one used in the code sample. This threw an error when trying to start the Windows Service. If I knew nothing of Windows Services, I wouldn't have been able to track down the source of the error in the Application event log. This article should be modified to include the namespace that is in the configuration file example around step 5.
Re: Host a WCF Service in a Managed Windows Service
The above code is based on .NET Framework 3.5. Therefore, you guys should pay attention to this point.
how i wiill consume this wcf service into a web application
how i will consume into a web application.....
"The WCFWindowsServiceSample service on local computer started and then stopped."
I build this project from scratch in VB and it did NOT work correctly.  It gave the following error when attempting to start the project: "The WCFWindowsServiceSample service on local computer started and then stopped..."  I built it using the C# code instead and the C# project installed and started just fine.  I was dumbstruck.

FINDING:  Step #3 of the instructions state: "Change the namespace to Microsoft.ServiceModel.Samples."  So, in the C# project I went into the project properties and edited the namespace field to be Microsoft.ServiceModel.Samples.  Everything worked fine.  When I did the same on the VB project I actually got an error that it couldn't find the default main() function to run and made me pick it from a list.  Strangely, the only option started out with "Microsoft.ServiceModel.Samples.Microsoft.ServiceModel.Samples....".  Which made start thinking something was screwy with the VB namespace.  COME TO FIND OUT, the namespace field for the C# project was actually titled "Default Namespace" while the VB field was titled "Root Namespace".  While I thought I was doing the same thing in each step, I was actually setting two slightly different properties that sat in the same place on the properties page.  Why is C#/VB different like this???

FIX:  For the VB project, set the Root Namespace field to nothing, for the C# project, set the Default Namespace field to "Microsoft.ServiceModel.Samples".
Separate Projects
I fully agree with PJBlecha, it is more natural to follow a
guide from a given template (isnt that what they are there for). Plus, having
two separate projects (i.e.  one for Win
Service and one for WCF Service) should be the way to create this solution, not
have them merged in to one. I’ve been unsuccessful at creating a solution with
two projects, if some knows how, please let the rest of us know. Tnx

TCP error 10061
I have created a windows service to host a wcf service with nettcp bindings. $0$0 $0 $0When I host the WCF service in a console host everything works fine but as soon as I pout it into a windows service my client will not connect raising an exception: "Metadata contains a reference that could not be resolved 'net.tcp://CS2066:8523/CSDRMS_BI/mex'" and a TCP error code 10061.$0 $0 $0 $0$0 $0 $0However I do not think this message is any different to when trying to connect wile the service is closed$0 $0$0 $0 $0I am sure the host opens in the windows service with the given address as I have messages output in an event log but I cannot get a client to connect despite being able to connect to a console host.$0 $0$0 $0 $0I would be grateful for any help on this matter.$0 $0Thanks$0 $0$0 $0
service not starting
I copied and pasted the code into my c# console application added a config file. Installed the services exe.But whenever i start the service i get the follwoing error

wcfwindowsservicesample service on local computer started and stopped. some service stop automatically if they are not in use by other service or programs.

the service runs in system account.


service not starting
I copied and pasted the code into my c# console application added a config file. Installed the services exe.But whenever i start the service i get the follwoing error

wcfwindowsservicesample service on local computer started and stopped. some service stop automatically if they are not in use by other service or programs.

the service runs in system account.


How to use VS2010 Windows Service project?
It would be a lot more helpful if this how-to also included directions on developing a service using the default Windows Service project template.

For those who say "it's all the same," no, it is NOT all the same.  The Windows Service template uses a partial class for the ServiceBase and separates the Main() method into a Program class, neither of which are germane to this how-to.

Also, in the real world, nobody is going to build a single project that encompasses all functionality.  Some reasonable expectations for how to build this as a solution, not a single project, are not out of bounds.
Deployment scripts blog post
I have made a blog post showing how to create batch files to install & start the service; or stop & uninstall.

http://richardwilburn.wordpress.com/2010/12/01/wcf-windows-service-deployment/
A Blog Post With Source Built From this article
As part of learning how to do this, I build the application described above in Visual Studio 2010, added a console project that demonstrates it's use and also a WPF calculator application that uses the service.

You can find the blog post that includes a reference to the source code here:

http://peterkellner.net/2010/06/18/wcf-service-in-managed-windows-service-vs2010-2/

Hope this helps!
A Blog Post With Source Built From this article
As part of learning how to do this, I build the application described above in Visual Studio 2010, added a console project that demonstrates it's use and also a WPF calculator application that uses the service.

You can find the blog post that includes a reference to the source code here:

http://peterkellner.net/2010/06/18/wcf-service-in-managed-windows-service-vs2010-2/