Postupy: Hostování služby WCF ve spravované službě Windows
Toto téma popisuje základní kroky potřebné k vytvoření služby WCF (Windows Communication Foundation), která je hostována službou systému Windows. Scénář je povolen možností hostování spravované služby Windows, která je dlouhotrvající služba WCF hostovaná mimo službu Internetová informační služba (IIS) v zabezpečeném prostředí, které není aktivováno zprávou. Životnost služby je řízena operačním systémem. Tato možnost hostování je dostupná ve všech verzích Windows.
Služby Systému Windows je možné spravovat pomocí modulu Microsoft.ManagementConsole.SnapIn v konzole Microsoft Management Console (MMC) a lze je nakonfigurovat tak, aby se spouštěly automaticky při spuštění systému. Tato možnost hostování se skládá z registrace domény aplikace (AppDomain), která hostuje službu WCF jako spravovanou službu Windows, aby životnost procesu služby byla řízena Správcem řízení služeb (SCM) pro služby Windows.
Kód služby zahrnuje implementaci kontraktu služby, třídy služby systému Windows a třídy instalačního programu. Třída implementace služby je CalculatorService
služba WCF. Jedná se CalculatorWindowsService
o službu systému Windows. Pokud se chcete kvalifikovat jako služba systému Windows, třída dědí z ServiceBase
a implementuje OnStart
metody a OnStop
metody. V souboru < a0/0OnStart
ServiceHost> se vytvoří typ CalculatorService
a otevře se. Služba OnStop
je zastavena a uvolněna. Hostitel také zodpovídá za poskytnutí základní adresy hostiteli služby, který je nakonfigurovaný v nastavení aplikace. Instalační třída, která dědí z Installer, umožňuje program nainstalovat jako službu systému Windows nástrojem Installutil.exe.
Vytvoření služby a poskytnutí hostitelského kódu
Vytvořte nový projekt konzolové aplikace sady Visual Studio s názvem Služba.
Přejmenujte Program.cs na Service.cs.
Změňte obor názvů na
Microsoft.ServiceModel.Samples
.Přidejte odkazy na následující sestavení:
- System.ServiceModel.dll
- System.ServiceProcess.dll
- System.Configuration.Install.dll
Do Service.cs přidejte následující
using
direktivy.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
ICalculator
Definujte kontrakt služby, jak je znázorněno v následujícím kódu.// 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
Implementujte kontrakt služby do třídy volané
CalculatorService
, jak je znázorněno v následujícím kódu.// 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
Vytvořte novou třídu,
CalculatorWindowsService
která dědí z ServiceBase třídy. Přidejte místní proměnnou,serviceHost
která bude odkazovat na ServiceHost instanci.Main
Definování metody, která volá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
Přepište metodu OnStart(String[]) vytvořením a otevřením nové ServiceHost instance, jak je znázorněno v následujícím kódu.
// 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
Přepište metodu OnStop ServiceHost zavření, jak je znázorněno v následujícím kódu.
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
Vytvořte novou třídu,
ProjectInstaller
která dědí z Installer a která je označena nastavenou RunInstallerAttribute natrue
. To umožňuje instalaci služby systému Windows nástrojem Installutil.exe.// 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
Odeberte třídu, která byla vygenerována při vytváření projektu.Přidejte do projektu konfigurační soubor aplikace. Nahraďte obsah souboru následujícím kódem XML konfigurace.
<?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>
Pravým tlačítkem myši klikněte na soubor App.config v Průzkumník řešení a vyberte Vlastnosti. V části Kopírovat do výstupního adresáře vyberte Kopírovat, pokud je novější.
Tento příklad explicitně určuje koncové body v konfiguračním souboru. Pokud do služby nepřidáte žádné koncové body, modul runtime za vás přidá výchozí koncové body. V tomto příkladu, protože služba má nastavenou ServiceMetadataBehavior hodnotu
true
, má služba také povolená metadata publikování. Další informace o výchozích koncových bodech, vazbách a chování najdete v tématu Zjednodušená konfigurace a zjednodušená konfigurace pro služby WCF.
Instalace a spuštění služby
Sestavte řešení pro vytvoření spustitelného
Service.exe
souboru.Otevřete Příkazový řádek pro vývojáře pro Visual Studio a přejděte do adresáře projektu. Zadejte
installutil bin\service.exe
na příkazovém řádku, aby se nainstalovala služba Systému Windows.Na příkazovém řádku zadejte
services.msc
přístup ke Správci řízení služeb (SCM). Služba Windows by se měla zobrazit ve službách jako WCFWindowsServiceSample. Služba WCF může reagovat pouze na klienty, pokud je spuštěná služba Windows. Chcete-li spustit službu, klikněte na ni pravým tlačítkem myši v SCM a vyberte "Start" nebo zadejte net start WCFWindowsServiceSample na příkazovém řádku.Pokud provedete změny služby, musíte ji nejprve zastavit a odinstalovat. Chcete-li službu zastavit, klikněte pravým tlačítkem myši na službu v SCM a vyberte "Zastavit" nebo zadejte net stop WCFWindowsServiceSample na příkazovém řádku. Všimněte si, že pokud službu Windows zastavíte a potom spustíte klienta, dojde k výjimce, EndpointNotFoundException když se klient pokusí o přístup ke službě. Chcete-li odinstalovat typ služby systému Windows installutil /u bin\service.exe na příkazovém řádku.
Příklad
Následuje úplný výpis kódu používaného v tomto tématu:
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
Podobně jako možnost "Samoobslužné hostování" vyžaduje hostitelské prostředí služby Windows, aby se v rámci aplikace napsal nějaký kód hostování. Služba se implementuje jako konzolová aplikace a obsahuje vlastní hostitelský kód. V jiných hostitelskýchprostředích službě (WAS) Internetová informační služba v jiných hostitelských prostředích, jako je služba windows Process Activation Service (WAS), není nutné psát kód hostování.