Aracılığıyla paylaş


Nasıl yapılır: Yönetilen Bir Windows Hizmetinde Bir WCF Hizmeti Barındırma

Bu konuda, bir Windows Hizmeti tarafından barındırılan bir Windows Communication Foundation (WCF) hizmeti oluşturmak için gereken temel adımlar özetlenmektedir. Senaryo, ileti etkinleştirilmemiş güvenli bir ortamda Internet Information Services (IIS) dışında barındırılan uzun süre çalışan bir WCF hizmeti olan yönetilen Windows hizmeti barındırma seçeneği tarafından etkinleştirilir. Hizmetin kullanım ömrü işletim sistemi tarafından denetlenır. Bu barındırma seçeneği Windows'un tüm sürümlerinde kullanılabilir.

Windows hizmetleri, Microsoft Yönetim Konsolu'nda (MMC) Microsoft.ManagementConsole.SnapIn ile yönetilebilir ve sistem önyüklendiğinde otomatik olarak başlatılacak şekilde yapılandırılabilir. Bu barındırma seçeneği, bir WCF hizmetini barındıran uygulama etki alanını (AppDomain) yönetilen Windows hizmeti olarak kaydetmeyi içerir, böylece hizmetin işlem ömrü Windows hizmetleri için Service Control Manager (SCM) tarafından denetlenır.

Hizmet kodu hizmet sözleşmesinin bir hizmet uygulamasını, bir Windows Hizmet sınıfını ve bir yükleyici sınıfını içerir. Hizmet uygulama sınıfı, CalculatorServicebir WCF hizmetidir. CalculatorWindowsService bir Windows hizmetidir. Bir Windows hizmeti olarak nitelendirmek için, sınıfı ve ServiceBase yöntemlerini devralır ve uygular OnStartOnStop . içinde OnStarttürü için CalculatorService bir ServiceHost oluşturulur ve açılır. içinde OnStophizmet durdurulur ve atılır. Ana bilgisayar, uygulama ayarlarında yapılandırılmış olan hizmet konağına bir temel adres sağlamakla da sorumludur. 'den Installerdevralan yükleyici sınıfı, programın Installutil.exe aracı tarafından bir Windows hizmeti olarak yüklenmesine izin verir.

Hizmeti oluşturma ve barındırma kodunu sağlama

  1. Service adlı yeni bir Visual Studio Konsol uygulaması projesi oluşturun.

  2. Program.cs Service.cs olarak yeniden adlandırın.

  3. Ad alanını olarak Microsoft.ServiceModel.Samplesdeğiştirin.

  4. Aşağıdaki derlemelere başvurular ekleyin:

    • System.ServiceModel.dll
    • System.ServiceProcess.dll
    • System.Configuration.Install.dll
  5. aşağıdaki using yönergeleri Service.cs ekleyin.

    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. Hizmet sözleşmesini ICalculator aşağıdaki kodda gösterildiği gibi tanımlayın.

    // 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. Hizmet sözleşmesini aşağıdaki kodda gösterildiği gibi adlı CalculatorService bir sınıfta uygulayın.

    // 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. sınıfından ServiceBase devralan adlı CalculatorWindowsService yeni bir sınıf oluşturun. Örneğe başvurmak ServiceHost için adlı serviceHost bir yerel değişken ekleyin. Çağıran Main yöntemi tanımlama 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. Aşağıdaki kodda OnStart(String[]) gösterildiği gibi yeni ServiceHost bir örnek oluşturup açarak yöntemini geçersiz kılın.

    // 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. Aşağıdaki kodda OnStop gösterildiği gibi yöntemini kapatarak ServiceHost geçersiz kılın.

    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. öğesinden Installer devralan ve olarak ayarlanmış trueolarak RunInstallerAttribute işaretlenmiş adlı ProjectInstaller yeni bir sınıf oluşturun. Bu, Windows hizmetinin Installutil.exe aracı tarafından yüklenmesini sağlar.

    // 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. Service Projeyi oluştururken oluşturulan sınıfı kaldırın.

  13. Projeye bir uygulama yapılandırma dosyası ekleyin. Dosyanın içeriğini aşağıdaki yapılandırma XML'iyle değiştirin.

    <?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>
    

    Çözüm Gezgini App.config dosyasına sağ tıklayın ve Özellikler'i seçin. Çıktı Dizinine Kopyala altında Daha Yeniyse Kopyala'yı seçin.

    Bu örnek, yapılandırma dosyasındaki uç noktaları açıkça belirtir. Hizmete herhangi bir uç nokta eklemezseniz, çalışma zamanı sizin için varsayılan uç noktaları ekler. Bu örnekte, hizmet ServiceMetadataBehavior olarak ayarlandığından true, hizmetinizde yayımlama meta verileri de etkindir. Varsayılan uç noktalar, bağlamalar ve davranışlar hakkında daha fazla bilgi için bkz. WCF Hizmetleri için Basitleştirilmiş Yapılandırma ve Basitleştirilmiş Yapılandırma.

Hizmeti yükleme ve çalıştırma

  1. Yürütülebilir dosyayı oluşturmak için çözümü oluşturun Service.exe .

  2. Visual Studio için Geliştirici Komut İstemi'ni açın ve proje dizinine gidin. Windows hizmetini yüklemek için komut istemine yazın installutil bin\service.exe .

    Hizmet Denetim Yöneticisi'ne (SCM) erişmek için komut istemine yazın services.msc . Windows hizmeti Hizmetler'de "WCFWindowsServiceSample" olarak görünmelidir. WCF hizmeti yalnızca Windows hizmeti çalışıyorsa istemcilere yanıt verebilir. Hizmeti başlatmak için SCM'de sağ tıklayın ve "Başlat" öğesini seçin veya komut istemine net start WCFWindowsServiceSample yazın.

  3. Hizmette değişiklik yaparsanız, önce hizmeti durdurmanız ve kaldırmanız gerekir. Hizmeti durdurmak için SCM'de hizmete sağ tıklayın ve "Durdur" seçeneğini belirleyin veya komut istemine net stop WCFWindowsServiceSample yazın. Windows hizmetini durdurup bir istemci çalıştırırsanız, istemci hizmete erişmeye çalıştığında bir EndpointNotFoundException özel durum oluştuğuna dikkat edin. Windows hizmetini kaldırmak için komut isteminde installutil /u bin\service.exe yazın.

Örnek

Bu konu tarafından kullanılan kodun tam listesi aşağıdadır:

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

"Kendi Kendine Barındırma" seçeneği gibi Windows hizmeti barındırma ortamı da uygulamanın bir parçası olarak bazı barındırma kodlarının yazılması gerekir. Hizmet bir konsol uygulaması olarak uygulanır ve kendi barındırma kodunu içerir. Internet Information Services'te (IIS) Windows İşlem Etkinleştirme Hizmeti (WAS) barındırma gibi diğer barındırma ortamlarında, geliştiricilerin barındırma kodu yazması gerekli değildir.

Ayrıca bkz.