Wednesday, 8 February 2012

C#.Net How To: Host a WCF Service in Windows Service using VS 2010

The WCF service can be hosted in IIS, Managed Windows Services, Windows Activation Service (WAS) and Self-hosting. I explained how to Host WCF service in IIS in my last post. Let’s learn here how to host WCF service in Managed Windows Services.

A windows service is a process managed by the Windows Operating System. Windows operating system always comes with the Service Control Manager, which controls various services installed on operating system of that machine.

Following are some advantages using Managed Windows Service as a WCF host option –
  • When system starts, the service will host automatically.
  • All versions of windows support hosting WCF service.
  • Service Control Manager controls the process life time of the service.
To host your WCF service inside a Windows service, you merely have to implement the Start() and Stop() methods of the Windows service.

The tutorial contains following steps –
a)   Creation of console application project.
b)   Implementation of WCF service.
c)   Adding Windows Services to WCF service.
d)   Adding Installer project to the solution.

In this tutorial we are creating a WCF service that returns a Welcome message.

1)   Create a new console application project.
Name it “WCFWindowsServiceHosting” and click OK button.
wcf create console application
WCF Service - Host Windows Service - Console Application Creation

2)   Rename the Program.cs to Welcome.cs and make it a public class. We will implement the service contract in this class later.

3)   Now add following three references –
i)             System.ServiceModel.dll
ii)           System.ServiceProcess.dll
iii)          System.Configuration.Install.dll
Add wcf windows service reference
WCF Service - Host Windows Service -Adding windows services references.
4)   We will need to define the Service Contract. Add a new interface named as “IWelcome” that will act as service contract.
add new item in service
WCF Service - Host Windows Service -Adding new item to the project
Add interface in wcf windows service
WCF Service - Host Windows Service -Adding Interface
Name this Interface as as IWelcome and click on Add button.

5)   Add following line in both Welcome.cs and IWelcome.cs files.

using System.ServiceModel;

6)   Add following code to the Service Contract i.e. IWelcome.cs
using System.ServiceModel;

namespace WCFWindowsServiceHosting
{
     //Define a service contract.
    [ServiceContract(Namespace="http://WCFWindowsServiceHosting")]
    public interface IWelcome
    {
        [OperationContract]
        String WelcomeMessage(String name);
    }
}
7)   Now implement the service contract. Go to Welcome.cs file, remove the main() method and add following code –
using System.ServiceModel;

namespace WCFWindowsServiceHosting
{
    public class Welcome : IWelcome
    {
        //Implement service contract.
        public String WelcomeMessage(String name)
        {
            return String.Format("Welcome to http://a1ashiish-csharp.blogspot.in, {0}", name);
        }
    }
}

8)   WCF service implementation is completed. The next step is to create a windows service. To create a new windows service, right click on the project name “WCFWindowsServiceHosting” and click on Add and then select New Item or Press Ctrl+Shift+A


Add wcf windows service project
WCF Service - Host Windows Service -Adding Windows Service Project.

Select Windows Service, name it as “WCFWindowsService” and click on Add button.
9)   You will get the designer view. Click on “Click here to switch to code view” to get the following –
Look at the code, WCFWindowsService class is inherited from ServiceBase class. To qualify as a Windows Service, the class inherits from the ServiceBase class and implements the OnStart and OnStop methods. Because the paradigm of starting Windows services is similar to starting your services inside WCF ServiceHost, you end up tying the lifetime of your WCF service to the lifetime of your Windows service.

10) Make the WCFWindowsService class public and add following line to the code.
using System.ServiceModel;

11) Add ServiceHost –
public ServiceHost serviceHost = null;

12) Now implement the OnStart method as shown below –
        protected override void OnStart(string[] args)
        {
            if (serviceHost != null)
                serviceHost.Close();

            serviceHost = new ServiceHost(typeof(Welcome));
            serviceHost.Open();
        }

13) Implement the OnStop method as shown below –
        protected override void OnStop()
        {
            if (serviceHost != null)
            {
                serviceHost.Close();
                serviceHost = null;
            }
        }

14) The final code will look like –
using System.ServiceModel;

namespace WCFWindowsServiceHosting
{
    public partial class WCFWindowsService : ServiceBase
    {
        public ServiceHost serviceHost = null;

        public WCFWindowsService()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            if (serviceHost != null)
                serviceHost.Close();

            serviceHost = new ServiceHost(typeof(Welcome));
            serviceHost.Open();
        }

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

15) Now add Configuration file i.e app.config to define the end points. Right click on project “WCFWindowsServiceHosting” and select Add and New items. Select “Application Configuration File.” And click on Add button
Add app.config in wcf service
WCF Service - Host Windows Service -Adding Configuration File i.e App.config

16) Copy below code and paste it in App.config file –

<?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="WCFWindowsServiceHosting.Welcome"
               behaviorConfiguration="MyServiceBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8000/WCFWindowsServiceHosting/Welcome"/>
          </baseAddresses>
        </host>
        <!-- this endpoint is exposed at the base address provided by host: http://localhost:8000/WCFWindowsServiceHosting/Welcome  -->
        <endpoint address=""
                  binding="wsHttpBinding"
                  contract="WCFWindowsServiceHosting.IWelcome" />
        <!-- the mex endpoint is exposed at http://localhost:8000/WCFWindowsServiceHosting/Welcome/mex -->
        <endpoint address="mex"
                  binding="mexHttpBinding"
                  contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="MyServiceBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="False"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

The WindowsService code is completed. The next step is to add the windows service installer to the project. Once service will be ready and running you will access the service by URL “http://localhost:8000/WCFWindowsServiceHosting/Welcome

17) To be able to install a service in the Service Control Manager, you have to add windows service installer to the project. Open designer view WCFWindowsServices class view, right click on the background of the view and select Add Installer property.
add wcf windows service installer
WCF Service - Host Windows Service -Adding Windows Service Installer

18) A ProjectInstaller.cs will get added into the solution explorer.
wcf windows service explorer
WCF Service - Host Windows Service -Solution Explorer view

19) Open the designer view of ProjectInstaller and right click serviceInstaller1 and select properties property to open the ServiceInstaller1 property window.
wcf service projectinstaller view
WCF Service - Host Windows Service -ProjectInstaller Desing view
ServiceInstaller property windows
WCF Service - Host Windows Service -ProjectInstaller - ServiceInstaller1 properties window.

20) Set the StartType to Automatic, so that the service gets started automatically every time the machine gets started.
service installer property window
WCF Service - Host Windows Service -ProjectInstaller - ServiceInstaller1 properties window.

The windows service installer code is completed. Now we will need a setup that can install the Windows Service in a machine. The next steps will describe how to add a Visual Studio Setup and Deployment project to the solution.  

21) Select File -> Add -> New Project
wcf service setup and deployment
WCF Service - Host Windows Service - Adding Setup and Deployment Project.

22) Go to Visual Studio Installer from Installed Templates and then select Setup project.
setup and deployment project
WCF Service - Host Windows Service -Adding Setup and Deployment Project
 Select the location and Click on Ok button.

23) In the solution explorer, right click on Setup project, go to Add and select Project Output…
adding output properties
WCF Service - Host Windows Service -Adding Project Output propeties to Setup

24) Select the Project “WCFWindowsServiceHosting”. Now select Primary Output and click on OK button.
Primary Output property to Setup
WCF Service - Host Windows Service -Adding Primary Output property to Setup
This will add a project item for the primary output of windows service to the setup project. The next step is to add custom actions to the executable file. These custom actions are Install, Commit, Rollback and Uninstall.

25) To add the custom actions, right click on setup1 project in solution explorer, goto View and select Custom Actions.
Adding Custom Actions
WCF Service - Host Windows Service -Adding Custom Actions
 26) The custom action view appears
Custom Actions view
WCF Service - Host Windows Service -Custom Action View
 27) Right click on Custom Actions and select Add Custom Action..
 add custom action in wcf
WCF Service - Host Windows Service -Adding custom action

28) A custom action – Select Item in Project window appears.
wcf custom action window
WCF Service - Host Windows Service -Custom Action Window

29) Double click on Application Folder in list box. Select Primary output from WCFWindowsServiceHosting and click on OK button.
Primary Output from window
WCF Service - Host Windows Service -Primary Output from window.

This will add Primary output from WCFWindowsServiceHosting to all custom actions.
Custom actions design view
WCF Service - Host Windows Service -Custom actions design view after adding Primary OutPut From.

The installer project is completed. Now build both project i.e “WCFWindowsServiceHosting” and “Setup1” to get the .msi in debug folder of Setup1 physical location.

30) Goto debug folder of “Setup1” project and install Setup1.msi. After successful installation of the Setup1, a service “Setup1” will add in the windows services. Open task manager and check the Services tab. You will get “WCFWindowsService” added in services. Right click on service and click on Start Service to start the service.
Installed wcf windows service
WCF Service - Host Windows Service -Task Manager showing the installed WCF service hosted in Windows Service.

31) Once service is started, you can access the WCF service by entering http://localhost:8000/WCFWindowsServiceHosting/Welcome in internet browser.

Sharing is Caring »»

12 comments:

  1. Thanks Ashish.
    Keep posting...

    -Abhijeet

    ReplyDelete
  2. There are lots of web articles on WCF, but are very confusing. Here is a simple and understandable article. Screenshots at every steps makes it very clear. Thanks a lot Ashish.
    All the best and Keep posting...

    ReplyDelete
  3. Thanks alot for this clear tutorial..
    I have some questions;
    how can i use the methods from explorer and how can i publish this service over the internet?

    ReplyDelete
    Replies
    1. I have followed the steps for this tutorial but I get an issue when i build, it complains that there is no entry point for "Main"
      Under Project properties there is no Startup Object

      thanks in advance

      Damian

      Delete
    2. Hi have the same error. How you solved the problem about main method? Thanks.

      Delete
    3. Pls add main method to WCFWindowsService.cs file. So the final code of this file looks :

      using System;
      using System.Collections.Generic;
      using System.ComponentModel;
      using System.Data;
      using System.Diagnostics;
      using System.Linq;
      using System.ServiceProcess;
      using System.Text;
      using System.ServiceModel;


      namespace WCFWindowsServiceHosting
      {
      public partial class WCFWindowsService : ServiceBase
      {
      public ServiceHost serviceHost = null;


      public WCFWindowsService()
      {
      InitializeComponent();
      }

      protected override void OnStart(string[] args)
      {
      if (serviceHost != null)
      serviceHost.Close();


      serviceHost = new ServiceHost(typeof(Welcome));
      serviceHost.Open();
      }


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

      static class HariProgram
      {
      static void Main(string[] args)
      {
      ServiceBase[] ServicesToRun;
      ServicesToRun = new ServiceBase[] { new WCFWindowsService() };
      ServiceBase.Run(ServicesToRun);

      }
      }
      }

      ***********************
      My name is Harikrushna Trivedi
      Email id : harikrushna.trivedi@ril.com

      Delete
    4. Very nice article but on installing the setup1.msi it is asking for user name and password. what should i give as user name and password

      Delete
  4. You posting are wonderful and informative.
    TopFive

    ReplyDelete
  5. I utterly attitude and revalue your bushel on each and every target.
    hostinghq.ca

    ReplyDelete
  6. Good one, Keep Posting more
    Thanks

    ReplyDelete
  7. I have been searching for hours and I haven’t found such awesome work.
    Hoster Talk

    ReplyDelete
  8. Hello, great Tutorial...

    but I have one Problem. When I want start the Service in services.msc, a message like "Error 1053: The service did not respond to the start or control request in a timely fashion" appears. Has someone any idea where my configuration isn't correct?

    ReplyDelete

Follow C# Tutorials