Export (0) Print
Expand All

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.

    Imports System.ComponentModel
    Imports System.ServiceModel
    Imports System.ServiceProcess
    Imports System.Configuration
    Imports 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()> _
        Function Add(ByVal n1 As Double, ByVal n2 As Double) As Double
        <OperationContract()> _
        Function Subtract(ByVal n1 As Double, ByVal n2 As Double) As Double
        <OperationContract()> _
        Function Multiply(ByVal n1 As Double, ByVal n2 As Double) As Double
        <OperationContract()> _
        Function Divide(ByVal n1 As Double, ByVal n2 As Double) As Double
    End Interface
    
    
  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
        Implements ICalculator
        ' Implement the ICalculator methods.
        Public Function Add(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Add
            Return n1 + n2
    
        End Function
    
        Public Function Subtract(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Subtract
            Return n1 - n2
    
        End Function
    
        Public Function Multiply(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Multiply
            Return n1 * n2
        End Function
    
        Public Function Divide(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Divide
            Return n1 / n2
    
        End Function
    End Class
    
    
  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
        Inherits ServiceBase
        Public serviceHost As ServiceHost = Nothing
        Public Sub New()
            ' Name the Windows Service
            ServiceName = "WCFWindowsServiceSample"
        End Sub
    
        Public Shared Sub Main()
            ServiceBase.Run(New CalculatorWindowsService())
        End Sub
    
    
  9. Override the OnStart method by creating and opening a new ServiceHost instance as shown in the following code.

    ' Start the Windows service.
    Protected Overrides Sub OnStart(ByVal args() As String)
        If serviceHost IsNot Nothing Then
            serviceHost.Close()
        End If
    
        ' Create a ServiceHost for the CalculatorService type and 
        ' provide the base address.
        serviceHost = New ServiceHost(GetType(CalculatorService))
    
        ' Open the ServiceHostBase to create listeners and start 
        ' listening for messages.
        serviceHost.Open()
    End Sub
    
    
  10. Override the OnStop method closing the ServiceHost as shown in the following code.

    Protected Overrides Sub OnStop()
        If serviceHost IsNot Nothing Then
            serviceHost.Close()
            serviceHost = Nothing
        End If
    End Sub
    
    
  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
           Inherits Installer
           Private process As ServiceProcessInstaller
           Private service As ServiceInstaller
    
           Public Sub New()
               process = New ServiceProcessInstaller()
               process.Account = ServiceAccount.LocalSystem
               service = New ServiceInstaller()
               service.ServiceName = "WCFWindowsServiceSample"
               Installers.Add(process)
               Installers.Add(service)
           End Sub
       End Class
    
    
  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.

Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text

Imports System.ComponentModel
Imports System.ServiceModel
Imports System.ServiceProcess
Imports System.Configuration
Imports System.Configuration.Install

Namespace Microsoft.ServiceModel.Samples
	' Define a service contract.
    <ServiceContract(Namespace:="http://Microsoft.ServiceModel.Samples")> _
    Public Interface ICalculator
        <OperationContract()> _
        Function Add(ByVal n1 As Double, ByVal n2 As Double) As Double
        <OperationContract()> _
        Function Subtract(ByVal n1 As Double, ByVal n2 As Double) As Double
        <OperationContract()> _
        Function Multiply(ByVal n1 As Double, ByVal n2 As Double) As Double
        <OperationContract()> _
        Function Divide(ByVal n1 As Double, ByVal n2 As Double) As Double
    End Interface

	' Implement the ICalculator service contract in a service class.
	Public Class CalculatorService
		Implements ICalculator
		' Implement the ICalculator methods.
		Public Function Add(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Add
            Return n1 + n2

		End Function

		Public Function Subtract(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Subtract
            Return n1 - n2

		End Function

		Public Function Multiply(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Multiply
            Return n1 * n2
        End Function

		Public Function Divide(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Divide
            Return n1 / n2

		End Function
	End Class

	Public Class CalculatorWindowsService
		Inherits ServiceBase
		Public serviceHost As ServiceHost = Nothing
		Public Sub New()
			' Name the Windows Service
			ServiceName = "WCFWindowsServiceSample"
		End Sub

		Public Shared Sub Main()
			ServiceBase.Run(New CalculatorWindowsService())
		End Sub

		' Start the Windows service.
		Protected Overrides Sub OnStart(ByVal args() As String)
			If serviceHost IsNot Nothing Then
				serviceHost.Close()
			End If

			' Create a ServiceHost for the CalculatorService type and 
			' provide the base address.
			serviceHost = New ServiceHost(GetType(CalculatorService))

			' Open the ServiceHostBase to create listeners and start 
			' listening for messages.
			serviceHost.Open()
		End Sub

		Protected Overrides Sub OnStop()
			If serviceHost IsNot Nothing Then
				serviceHost.Close()
				serviceHost = Nothing
			End If
		End Sub
	End Class
    ' Provide the ProjectInstaller class which allows 
    ' the service to be installed by the Installutil.exe tool
    <RunInstaller(True)> _
 Public Class ProjectInstaller
        Inherits Installer
        Private process As ServiceProcessInstaller
        Private service As ServiceInstaller

        Public Sub New()
            process = New ServiceProcessInstaller()
            process.Account = ServiceAccount.LocalSystem
            service = New ServiceInstaller()
            service.ServiceName = "WCFWindowsServiceSample"
            Installers.Add(process)
            Installers.Add(service)
        End Sub
    End Class
End Namespace

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

Community Additions

ADD
Show:
© 2015 Microsoft