Simplify.WindowsServices
2.14.1
This package is maintained for critical bugs, but not for new features.
dotnet add package Simplify.WindowsServices --version 2.14.1
NuGet\Install-Package Simplify.WindowsServices -Version 2.14.1
<PackageReference Include="Simplify.WindowsServices" Version="2.14.1" />
paket add Simplify.WindowsServices --version 2.14.1
#r "nuget: Simplify.WindowsServices, 2.14.1"
// Install Simplify.WindowsServices as a Cake Addin #addin nuget:?package=Simplify.WindowsServices&version=2.14.1 // Install Simplify.WindowsServices as a Cake Tool #tool nuget:?package=Simplify.WindowsServices&version=2.14.1
Simplify.WindowsServices Documentation
Provides BasicServiceHandler
, SingleTaskServiceHandler
, MultitaskServiceHandler
windows-services base classes, ServiceInstallerBase
installation base class.
Allows you to simply create and use windows services. Every user class instance will be instantiated using Simplify.DI IOC container which provides DI by default for your windows services.
Available at NuGet as binary package
Principle of work
To use Simplify.WindowsServices, you must create a class with the Run
method in it and pass this class to the handler as a type parameter. The Run
method will be invoked by the handler class (the handler types are listed below), this method will be your execution process root. An instance of your class will be created using the IOC Simplify.DI
container, so you can register any types that your class depends on through DIContainer.Current
, and they will be automatically resolved.
Run
method can be one of the following:
- Parameterless
Run()
method. Run(string serviceName)
if you want to access a service name.Run(IJobArgs args)
if you want to access a service name or startup parameters.
Run method can be void
or can return Task
(can be used for async/await code).
Quick start
There is a templates package available at nuget.org for Simplify.WindowsServices.
Install the Simplify.WindowsServices templates package:
dotnet new -i Simplify.WindowsServices.Templates
Create an initial Simplify.WindowsServices based project:
dotnet new simplify.windowsservice -n HelloWorld
Or create an initial Simplify.WindowsServices + work with database based project:
dotnet new simplify.windowsservicewithdatabase -n HelloWorld
BasicServiceHandler
BasicServiceHandler class is best suited for services that run without timers, for example, a TCP server or client.
Example
MyClass.cs
public class MyClass
{
public void Run()
{
// Some task
}
}
Program.cs
static void Main(string[] args)
{
new BasicServiceHandler<MyClass>(true).Start(args);
}
The true parameter indicates what MyClass
class will be automatically registered in DIContainer.Current
like DIContainer.Current.Register<MyClass>();
otherwise you should do it manually:
static void Main(string[] args)
{
DIContainer.Current.Register<MyClass>();
new BasicServiceHandler<MyClass>().Start(args);
}
SingleTaskServiceHandler
SingleTaskServiceHandler
class is best suited to perform one task, which must be periodically started by a timer.
You can specify timer intervals in seconds or just set the Ncrontab expression for timer. This options should be set via configuration. If no settings specified in a config, then the timer will be executed once every minute. If both timer interval and crontab expression specified in the config, then the crontab expression will be used instead.
Example
App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="ServiceSettings" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</configSections>
<ServiceSettings>
<add key="CrontabExpression" value="* * * * *" />
<add key="ProcessingInterval" value="30" />
</ServiceSettings>
</configuration>
For crontab expression examples see
Multiple crontab expressions can be specified, for example: 30 14 * * *|45 1 * * *|0 12 * * Mon
SingleTaskServiceHandler working example
MyClass.cs
public class MyClass
{
public void Run()
{
// Some task
}
}
Program.cs
static void Main(string[] args)
{
new SingleTaskServiceHandler<MyClass>(true).Start(args);
}
MultitaskServiceHandler
MultitaskServiceHandler
class is best suited for multiple tasks services.
This is the same as SingleTaskServiceHandler
but allows you to specify multiple working classes/methods.
You can add multiple jobs with different timer intervals/crontab expressions.
You can use single class with several methods, each specified method will be launched by the corresponding task (a new instance of the class will be created), or simply use several classes.
Example
MultitaskServiceHandler working example
Program.cs
static void Main(string[] args)
{
// Handler creation
var handler = new MultitaskServiceHandler();
// Jobs addition
// If configuration section is not specified then 'YourClassName + Settings' section name will be used
handler.AddJob<TaskProcessor1>(true);
// Manually specified section name and invoke method name
handler.AddJob<TaskProcessor1>("TaskProcessor1SecondTaskSettings", "RunTask2");
// Registering class manually
DIContainer.Current.Register<TaskProcessor2>();
handler.AddJob<TaskProcessor2>();
handler.Start(args);
}
TaskProcessor1.cs
public class TaskProcessor1
{
public void Run()
{
Debug.WriteLine("TaskProcessor1 Run executed");
}
public void RunTask2()
{
Debug.WriteLine("TaskProcessor1 RunTask2 executed");
}
}
TaskProcessor2.cs
public class TaskProcessor2
{
public void Run()
{
Debug.WriteLine("TaskProcessor2 Run executed");
}
}
App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="TaskProcessor1Settings" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<section name="TaskProcessor1SecondTaskSettings" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<section name="TaskProcessor2Settings" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</configSections>
<TaskProcessor1Settings>
<add key="CrontabExpression" value="*/2 * * * *" />
</TaskProcessor1Settings>
<TaskProcessor1SecondTaskSettings>
<add key="ProcessingInterval" value="30" />
</TaskProcessor1SecondTaskSettings>
<TaskProcessor2Settings>
<add key="ProcessingInterval" value="45" />
</TaskProcessor2Settings>
</configuration>
Services installation/uninstallation
If you pass the args
parameter from your Main
method to the Start
handler method, then you can install/uninstall the service using the service command line parameters.
Installation example
MyService.exe install
Uninstallation example
MyService.exe uninstall
Windows-service installer base class
ServiceInstallerBase
class allows you to install a windows service with information from your assembly information fields, like Title
, Description
.
Description
and Title
fields of a specified assembly will be used as your service name and description.
Title
will be used as a service IDDescription
will be used as a service name and description (you will be able to see that information inServices.msc
after service will be installed).
Default ServiceInstallerBase usage
[RunInstaller(true)]
public class ServiceInstaller : ServiceInstallerBase
{
}
Specifying service "RunAs" user
Through the configuration file, you can specify the username and password under which the service will be launched.
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="ServiceInstallerSettings" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</configSections>
<ServiceInstallerSettings>
<add key="RunAsUserName" value="UserName"/>
<add key="RunAsUserPassword" value="UserPassword"/>
</ServiceInstallerSettings>
</configuration>
Specifying service system account
You can specify the service system account under which the service will be launched.
<ServiceInstallerSettings>
<add key="ServiceAccount" value="NetworkService"/>
</ServiceInstallerSettings>
Possible values: LocalService
, NetworkService
, LocalSystem
Note: if RunAsUserName and RunAsUserPassword is set in the config, then the ServiceAccount parameter will be ignored.
Note: you can specify any user, for example: domain user as "YourDomain\UserName".
Additional settings
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="ServiceSettings" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</configSections>
<ServiceSettings>
<add key="CleanupOnTaskFinish" value="true" />
<add key="MaximumParallerTasksCount" value="2" />
</ServiceSettings>
</configuration>
Microsoft.Extensions.Configuration
support in Simplify.WindowsServices
Simplify.WindowsServices support configuration via IConfiguration
instead of old ConfigurationManager
App.config
, just use one of the respective handler methods
Example
Program.cs
...
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", false)
.Build();
var handler = new SingleTaskServiceHandler<MyClass>(configuration);
...
appsettings.json
{
"ServiceSettings":
{
"CrontabExpression": "* * * * *"
}
}
Global exceptions catching which can be thrown when resolving instances by Simplify.DI in handler
Simplify.WindowsService can catch all exceptions thrown by a user code To receive such catch event you should subscribe to handler OnException event.
static void Main(string[] args)
{
var handler = new SingleTaskServiceHandler<MyClass>();
handler.OnException += OnException;
hander.Start(args);
}
static void OnException(ServiceExceptionArgs args)
{
Console.Write(args.ServiceName);
Console.Write(args.Exception.Message);
}
DI example
Classes
public interface IMyClass2
{
SomeMethod();
}
public class MyClass2 : IMyClass2
{
public SomeMethod()
{
}
}
public class MyClass
{
private IMyClass2 _myclass2;
public MyClass(IMyClass2 myclass2)
{
_myclass2 = myclass2;
}
public void Run()
{
_myclass2.SomeMethod();
}
}
Program.cs
static void Main(string[] args)
{
DIContainer.Current.Register<IMyClass2, MyClass2>();
DIContainer.Current.Register<MyClass>();
new SingleTaskServiceHandler<MyClass>().Start(args);
}
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET Framework | net48 is compatible. net481 was computed. |
-
.NETFramework 4.8
- Microsoft.Extensions.Configuration (>= 3.1.32)
- ncrontab (>= 3.3.1)
- Simplify.DI (>= 4.2.10)
- Simplify.System (>= 1.6.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated | |
---|---|---|---|
2.14.1 | 1,118 | 8/24/2023 | |
2.14.0 | 1,298 | 11/18/2021 | |
2.13.0 | 731 | 2/4/2021 | |
2.12.1 | 431 | 2/2/2021 | |
2.12.0 | 1,119 | 12/9/2019 | |
2.10.0 | 787 | 9/26/2019 | |
2.9.1 | 598 | 9/12/2019 | |
2.9.0 | 660 | 7/2/2019 | |
2.8.1 | 679 | 6/23/2019 | |
2.8.0 | 844 | 12/20/2018 | |
2.7.0 | 793 | 12/5/2018 | |
2.6.0 | 1,123 | 3/14/2018 | |
2.5.0 | 1,155 | 8/15/2017 | |
2.4.0 | 1,257 | 8/19/2016 | |
2.3.0 | 1,072 | 4/29/2016 | |
2.2.0 | 1,259 | 1/10/2016 | |
2.1.2 | 3,031 | 11/10/2014 | |
2.1.1 | 2,077 | 11/5/2014 | |
2.1.0 | 2,266 | 11/5/2014 | |
2.0.0 | 1,370 | 10/16/2014 | |
1.0.3 | 1,479 | 8/15/2014 | |
1.0.2 | 1,172 | 5/21/2014 | |
1.0.1 | 1,153 | 4/28/2014 | |
1.0.0 | 1,239 | 2/25/2014 |