I thought I'd blog an example here for reference:
- class Program {
- static void Main() {
- if (Environment.UserInteractive) {
- ServiceManager serviceManager = new ServiceManager();
- serviceManager.OpenAll();
- Console.ReadKey();
- serviceManager.CloseAll();
- }
- else
- ServiceBase.Run(new WindowsService());
- }
- }
- public class WindowsService : ServiceBase
- {
- public static string WindowsServiceName = "Windows Service Name";
- public static string WindowsServiceDescription = "Windows Service Description";
- public static string WindowsServiceUsername = @".\username";
- public static string WindowsServicePassword = "password";
- private readonly ServiceManager serviceManager = new ServiceManager();
- private readonly IContainer components = new Container();
- protected override void Dispose(bool disposing) {
- if (serviceManager != null) serviceManager.CloseAll();
- if (disposing && (components != null)) components.Dispose();
- base.Dispose(disposing);
- }
- public WindowsService() {
- ServiceName = WindowsServiceName;
- CanStop = true;
- }
- protected override void OnStart(string[] args) {
- base.OnStart(args);
- serviceManager.OpenAll();
- }
- protected override void OnStop() {
- serviceManager.CloseAll();
- base.OnStop();
- }
- }
- public class ServiceManager {
- readonly List<servicehost> serviceHosts = new List<servicehost>();
- public void OpenAll() {
- OpenHost<service1>();
- OpenHost<service2>();
- ...
- }
- public void CloseAll() {
- foreach (ServiceHost serviceHost in serviceHosts)
- serviceHost.Close();
- }
- private void OpenHost<t>() {
- Type type = typeof(T);
- ServiceHost serviceHost = new ServiceHost(type);
- serviceHost.Open();
- serviceHosts.Add(serviceHost);
- }
- }
- /// <remarks>
- /// Enables application to be installed as a Windows Service by running InstallUtil
- /// </remarks>
- [RunInstaller(true)]
- public class WcfServiceHostInstaller : Installer {
- public WcfServiceHostInstaller() {
- Installers.Add(new ServiceInstaller
- {
- StartType = ServiceStartMode.Automatic,
- ServiceName = WindowsService.WindowsServiceName,
- Description = WindowsService.WindowsServiceDescription
- });
- Installers.Add(new ServiceProcessInstaller { Account = ServiceAccount.User, Username = WindowsService.WindowsServiceUsername, Password = WindowsService.WindowsServicePassword });
- }
- }</t></service2></service1></servicehost></servicehost>
And some configuration:
- Here, the binding & behaviour configuration is shared across services but you may need different configurations for different types of services.
- I use different ports for different services, but you don't have to.
- <system.serviceModel>
- <services>
- <service behaviorConfiguration="DefaultBehavior" name="Namespace.Service1">
- <endpoint address="" binding="netTcpBinding" bindingConfiguration="TCPBindingConfig" name="TCPEndpoint" contract="Namespace.IService1" />
- <endpoint address="mex" binding="mexTcpBinding" bindingConfiguration="" name="TcpMetaData" contract="IMetadataExchange" />
- <host>
- <baseAddresses>
- <add baseAddress="net.tcp://localhost:8001/Namespace/Service1" />
- </baseAddresses>
- </host>
- </service>
- <service behaviorConfiguration="DefaultBehavior" name="Namespace.Service2">
- <endpoint address="" binding="netTcpBinding" bindingConfiguration="TCPBindingConfig" name="TCPEndpoint" contract="Namespace.IService2" />
- <endpoint address="mex" binding="mexTcpBinding" bindingConfiguration="" name="TcpMetaData" contract="IMetadataExchange" />
- <host>
- <baseAddresses>
- <add baseAddress="net.tcp://localhost:8002/Namespace/Service2" />
- </baseAddresses>
- </host>
- </service>
- ...
- </services>
- <bindings>
- <netTcpBinding>
- <binding name="TCPBindingConfig" maxBufferSize="5242880" maxReceivedMessageSize="5242880">
- <readerQuotas maxStringContentLength="5242880" />
- <security mode="None" />
- </binding>
- </netTcpBinding>
- </bindings>
- <behaviors>
- <serviceBehaviors>
- <behavior name="DefaultBehavior">
- <serviceMetadata httpGetEnabled="false" />
- <serviceDebug includeExceptionDetailInFaults="true" />
- <serviceThrottling maxConcurrentCalls="21" maxConcurrentSessions="50" />
- </behavior>
- </serviceBehaviors>
- </behaviors>
- </system.serviceModel>