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ı, CalculatorService
bir WCF hizmetidir. CalculatorWindowsService
bir Windows hizmetidir. Bir Windows hizmeti olarak nitelendirmek için, sınıfı ve ServiceBase
yöntemlerini devralır ve uygular OnStart
OnStop
. içinde OnStart
türü için CalculatorService
bir ServiceHost oluşturulur ve açılır. içinde OnStop
hizmet 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
Service adlı yeni bir Visual Studio Konsol uygulaması projesi oluşturun.
Program.cs Service.cs olarak yeniden adlandırın.
Ad alanını olarak
Microsoft.ServiceModel.Samples
değiştirin.Aşağıdaki derlemelere başvurular ekleyin:
- System.ServiceModel.dll
- System.ServiceProcess.dll
- System.Configuration.Install.dll
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
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
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
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ğıranMain
yöntemi tanımlamaServiceBase.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
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
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
öğesinden Installer devralan ve olarak ayarlanmış
true
olarak 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
Service
Projeyi oluştururken oluşturulan sınıfı kaldırın.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
Yürütülebilir dosyayı oluşturmak için çözümü oluşturun
Service.exe
.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.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.