WFC services are a good way to spit a complex and demanding application into smaller parts and use more system resources, but not only. In the literature there are several information why you should use WFC (ex: Distributed apps in a local network etc)… In this example you will find a complete Visual studio project which hosts a wcf service inside a windows service.
Our service has two exposed methods (but you can add yours):
public string Echo(string text)
public string GetServiceName()
Moreover our Windows service will be able to install and uninstall itself directly by using startup args:
MyService.exe -install
MyService.exe -uninstall
Let’s Start
- Before start putting our code we have to perform some configurations as described below:
The first file we will create is the ServiceConfiguration.cs which will contain some information regarding our service that will be needed later on in the project
using System.Reflection;
namespace MyService
{
public static class ServiceConfiguration
{
public static readonly string ServiceName = "MyService";
public static readonly string ExecutingAssebmlyLocation = Assembly.GetExecutingAssembly().Location;
public static readonly string UrlPort = "8000";
}
}
The second file we will create is the ProjectInstaller.cs and it should contail all the information that the project needs to install and uninstall our service
using System;
using System.ComponentModel;
using System.Configuration.Install;
using System.ServiceProcess;
namespace MyService
{
[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 = ServiceConfiguration.ServiceName;
service.StartType = ServiceStartMode.Automatic;
Installers.Add(process);
Installers.Add(service);
}
public static bool Install()
{
try
{
ManagedInstallerClass.InstallHelper(new string[] {ServiceConfiguration.ExecutingAssebmlyLocation });
StartService(ServiceConfiguration.ServiceName, 7000);
}
catch
{
return false;
}
return true;
}
public static bool Uninstall()
{
StopService(ServiceConfiguration.ServiceName, 7000);
try
{
ManagedInstallerClass.InstallHelper(new string[] { "/u", ServiceConfiguration.ExecutingAssebmlyLocation });
}
catch
{
return false;
}
return true;
}
public static void StartService(string serviceName, int timeoutMilliseconds)
{
ServiceController service = new ServiceController(serviceName);
try
{
service.Start();
service.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromMilliseconds(timeoutMilliseconds));
}
catch (Exception ex)
{
//....
}
}
public static void StopService(string serviceName, int timeoutMilliseconds)
{
ServiceController service = new ServiceController(serviceName);
try
{
service.Stop();
service.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromMilliseconds(timeoutMilliseconds));
}
catch (Exception ex)
{
//....
}
}
}
}
Now we will create the WCFService.cs which will contain our actual service
using System.ServiceModel;
namespace MyService
{
[ServiceContract(Namespace = "http://MyService")]
public interface IWCFService
{
[OperationContract]
string Echo(string text);
[OperationContract]
string GetServiceName();
}
public class WCFService : IWCFService
{
public string Echo(string text)
{
return text;
}
public string GetServiceName()
{
return ServiceConfiguration.ServiceName;
}
}
}
And finally, our last file WService.cs hosting the source code of the Window Service
using System;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceProcess;
namespace MyService
{
public class WService : ServiceBase
{
public ServiceHost serviceHost = null;
public WService()
{
ServiceName = ServiceConfiguration.ServiceName;
}
public static void Main(string[] args)
{
if (args != null && args.Length != 0 && args[0].Length >= 1 && (args[0][0] == '-' || args[0][0] == '/'))
{
switch (args[0].Substring(1).ToLower())
{
default:
break;
case "i":
ProjectInstaller.Install();
break;
case "u":
ProjectInstaller.Uninstall();
break;
}
}
else
{
ServiceBase.Run(new WService());
}
}
protected override void OnStart(string[] args)
{
try
{
if (serviceHost != null)
serviceHost.Close();
Uri httpBaseAddress = new Uri($"http://{System.Net.Dns.GetHostName()}:{ServiceConfiguration.UrlPort}/{ServiceConfiguration.ServiceName}/service");
serviceHost = new ServiceHost(typeof(WCFService), httpBaseAddress);
WSHttpBinding wsHttpBinding = new WSHttpBinding();
wsHttpBinding.MaxReceivedMessageSize = 70000;
wsHttpBinding.MessageEncoding = WSMessageEncoding.Text;
serviceHost.AddServiceEndpoint(typeof(IWCFService), wsHttpBinding, "");
serviceHost.Description.Behaviors.Add(new ServiceMetadataBehavior() { HttpGetEnabled = true });
serviceHost.Open();
}
catch (Exception ex)
{
EventLog.WriteEntry(ex.ToString());
}
}
protected override void OnStop()
{
if (serviceHost != null)
{
serviceHost.Close();
serviceHost = null;
}
}
}
}
Now if you open a command line (admin rights) and navigate to your executable, you can write MyService.exe -i or MyService -u to install and run or stop and uninstall your service
https://github.com/devcoons/example-wcf-windows-service
–