Procedura: ospitare un servizio WCF in un servizio Windows gestitoHow to: Host a WCF Service in a Managed Windows Service

In questo argomento vengono illustrati i passaggi di base necessari per creare un servizio Windows Communication Foundation (WCF) ospitato da un servizio Windows.This topic outlines the basic steps required to create a Windows Communication Foundation (WCF) service that is hosted by a Windows Service. Lo scenario è abilitato dall'opzione di hosting del servizio Windows gestito che è un servizio WCF con esecuzione prolungata ospitato all'esterno di Internet Information Services (IIS) in un ambiente protetto che non viene attivato tramite messaggio.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. La durata del servizio è controllata invece dal sistema operativo.The lifetime of the service is controlled instead by the operating system. Questa opzione di hosting è disponibile in tutte le versioni di Windows.This hosting option is available in all versions of Windows.

I servizi Windows possono essere gestiti con Microsoft.ManagementConsole.SnapIn in Microsoft Management Console (MMC) e possono essere configurati per essere avviati automaticamente all'avvio del sistema.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. Questa opzione di hosting consiste nella registrazione del dominio applicazione (AppDomain) che ospita un servizio WCF come servizio Windows gestito, in modo che la durata del processo del servizio sia controllata da Gestione controllo servizi (SCM) per i servizi Windows.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.

Il codice del servizio include un'implementazione del contratto di servizio, una classe di servizio Windows e una classe del programma di installazione.The service code includes a service implementation of the service contract, a Windows Service class, and an installer class. La classe di implementazione del servizio, CalculatorService, è un servizio WCF.The service implementation class, CalculatorService, is a WCF service. CalculatorWindowsService è un servizio Windows.The CalculatorWindowsService is a Windows service. Per essere qualificata come servizio Windows, la classe eredita da ServiceBase e implementa i metodi OnStart e OnStop.To qualify as a Windows service, the class inherits from ServiceBase and implements the OnStart and OnStop methods. In OnStart, viene creata e aperta una classe ServiceHost per il tipo CalculatorService.In OnStart, a ServiceHost is created for the CalculatorService type and opened. In OnStop, il servizio viene interrotto ed eliminato.In OnStop, the service is stopped and disposed. L'host è inoltre responsabile di fornire un indirizzo di base all'host del servizio, che è stato configurato nelle impostazioni dell'applicazione.The host is also responsible for providing a base address to the service host, which has been configured in application settings. La classe del programma di installazione, che eredita da Installer, consente al programma di essere installato come servizio Windows dallo strumento Installutil.exe.The installer class, which inherits from Installer, allows the program to be installed as a Windows service by the Installutil.exe tool.

Costruire il servizio e fornire il codice hostConstruct the service and provide the hosting code

  1. Creare un nuovo progetto di app console di Visual Studio denominato servizio.Create a new Visual Studio Console app project called Service.

  2. Rinominare Program.cs come Service.cs.Rename Program.cs to Service.cs.

  3. Modificare lo spazio dei nomi in Microsoft.ServiceModel.Samples.Change the namespace to Microsoft.ServiceModel.Samples.

  4. Aggiungere riferimenti agli assembly riportati di seguito:Add references to the following assemblies:

    • System.ServiceModel.dllSystem.ServiceModel.dll

    • System.ServiceProcess.dllSystem.ServiceProcess.dll

    • System.Configuration.Install.dllSystem.Configuration.Install.dll

  5. Aggiungere le istruzioni using seguenti a Service.cs.Add the following using statements to Service.cs.

    using System.ComponentModel;
    using System.ServiceModel;
    using System.ServiceProcess;
    using System.Configuration;
    using System.Configuration.Install;
    
    Imports System.ComponentModel
    Imports System.ServiceModel
    Imports System.ServiceProcess
    Imports System.Configuration
    Imports System.Configuration.Install
    
  6. Definire il contratto di servizio ICalculator come mostrato nel codice seguente.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);
    }
    
    ' 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. Implementare il contratto di servizio in una classe denominata CalculatorService come illustrato nel codice seguente.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;
        }
    }
    
    ' 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. Creare una nuova classe denominata CalculatorWindowsService che eredita dalla classe ServiceBase.Create a new class called CalculatorWindowsService that inherits from the ServiceBase class. Aggiungere una variabile locale denominata serviceHost per fare riferimento all'istanza di ServiceHost.Add a local variable called serviceHost to reference the ServiceHost instance. Definire il metodo Main che chiama ServiceBase.Run(new CalculatorWindowsService)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());
        }
    
    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. Eseguire l'override del metodo OnStart(String[]) creando e aprendo una nuova istanza di ServiceHost come mostrato nel codice seguente.Override the OnStart(String[]) 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();
    }
    
    ' 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. Eseguire l'override del metodo OnStop chiudendo ServiceHost come mostrato nel codice seguente.Override the OnStop method closing the ServiceHost as shown in the following code.

    protected override void OnStop()
    {
        if (serviceHost != null)
        {
            serviceHost.Close();
            serviceHost = null;
        }
    }
    
    Protected Overrides Sub OnStop()
        If serviceHost IsNot Nothing Then
            serviceHost.Close()
            serviceHost = Nothing
        End If
    End Sub
    
  11. Creare una nuova classe denominata ProjectInstaller che eredita da Installer e che sia contrassegnata con RunInstallerAttribute impostato su true.Create a new class called ProjectInstaller that inherits from Installer and that is marked with the RunInstallerAttribute set to true. Questo consente l'installazione del servizio Windows mediante lo strumento Installutil.exe.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);
        }
    }
    
       ' 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. Rimuovere la classe Service generata al momento della creazione del progetto.Remove the Service class that was generated when you created the project.

  13. Aggiungere un file di configurazione dell'applicazione al progetto.Add an application configuration file to the project. Sostituire il contenuto del file con l'XML di configurazione riportato di seguito.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>
    

    Fare clic con il pulsante destro del mouse sul file app. config nel Esplora soluzioni e selezionare Proprietà.Right click the App.config file in the Solution Explorer and select Properties. In copia nella directory di output selezionare copia se più recente.Under Copy to Output Directory select Copy if Newer.

    In questo esempio vengono specificati in modo esplicito gli endpoint del file di configurazione.This example explicitly specifies endpoints in the configuration file. Se non vengono aggiunti endpoint al servizio, il runtime aggiunge gli endpoint predefiniti.If you do not add any endpoints to the service, the runtime adds default endpoints for you. In questo esempio, poiché il servizio ha ServiceMetadataBehavior impostato su true, è anche abilitata la pubblicazione di metadati.In this example, because the service has a ServiceMetadataBehavior set to true, your service also has publishing metadata enabled. Per altre informazioni su endpoint, associazioni e comportamenti predefiniti, vedere Simplified Configuration (Configurazione semplificata) e Simplified Configuration for WCF Services (Configurazione semplificata per servizi WCF).For more information about default endpoints, bindings, and behaviors, see Simplified Configuration and Simplified Configuration for WCF Services.

Installare ed eseguire il servizio .Install and run the service

  1. Compilare la soluzione per creare l'eseguibile Service.exe.Build the solution to create the Service.exe executable.

  2. Aprire Prompt dei comandi per gli sviluppatori per Visual Studio e passare alla directory del progetto.Open Developer Command Prompt for Visual Studio and navigate to the project directory. Digitare installutil bin\service.exe al prompt dei comandi per installare il servizio Windows.Type installutil bin\service.exe at the command prompt to install the Windows service.

    Digitare services.msc al prompt dei comandi per accedere a Gestione controllo servizi (SCM).Type services.msc at the command prompt to access the Service Control Manager (SCM). Il servizio Windows verrà visualizzato in Servizi come "WCFWindowsServiceSample".The Windows service should appear in Services as "WCFWindowsServiceSample". Il servizio WCF può rispondere ai client solo se il servizio Windows è in esecuzione.The WCF service can only respond to clients if the Windows service is running. Per avviare il servizio, fare clic con il pulsante destro del mouse su di esso in Gestione controllo servizi e scegliere "Avvia" oppure digitare net start WCFWindowsServiceSample al prompt dei comandi.To start the service, right-click it in the SCM and select "Start", or type net start WCFWindowsServiceSample at the command prompt.

  3. Se si apportano modifiche al servizio, è prima necessario arrestare il servizio e disinstallarlo.If you make changes to the service, you must first stop it and uninstall it. Per arrestare il servizio, fare clic con il pulsante destro del mouse sul servizio in SCM e selezionare "arresta" oppure digitare net stop WCFWindowsServiceSample al prompt dei comandi.To stop the service, right-click the service in the SCM and select "Stop", or type net stop WCFWindowsServiceSample at the command prompt. Si noti che se si arresta il servizio Windows e quindi si esegue un client, si verificherà un'eccezione EndpointNotFoundException quando un client tenta di accedere al servizio.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. Per disinstallare il servizio Windows digitare installutil/u bin\service.exe al prompt dei comandi.To uninstall the Windows service type installutil /u bin\service.exe at the command prompt.

EsempioExample

Di seguito è riportato un elenco completo del codice utilizzato in questo argomento: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);
        }
    }
}
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

Analogamente all'opzione di self-hosting, l'ambiente host del servizio Windows richiede che venga scritto codice di hosting come parte dell'applicazione.Like the "Self-Hosting" option, the Windows service hosting environment requires that some hosting code be written as part of the application. Il servizio viene implementato come applicazione console e contiene il proprio codice di hosting.The service is implemented as a console application and contains its own hosting code. In altri ambienti host, quali ad esempio l'host del servizio di attivazione dei processi di Windows (WAS, Windows Process Activation Service) in Internet Information Services (IIS), non è necessario che gli sviluppatori scrivano codice di hosting.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.

Vedere ancheSee also