Servicios de Windows con .NET

¿Qué es un servicio de Windows?

Un Servicio de Windows es una aplicación que se ejecuta en segundo plano en un sistema operativo Windows. A diferencia de un programa normal que requiere la interacción de un usuario, un servicio no tiene interfaz gráfica. Está diseñado para funcionar de forma continua e ininterrumpida, iniciando automáticamente cuando el sistema se enciende y deteniéndose únicamente cuando este se apaga.

¿Por qué debemos usar servicios de Windows?

Instrucciones para crear un servicio de Windows en .NET

  1. Creamos un proyecto Worker Service:
dotnet new worker -n MiWorkerService
  1. Instalamos el paquete necesario para ejecutar como servicio de Windows:
dotnet add package Microsoft.Extensions.Hosting.WindowsServices
  1. Modificamos el Program.cs y registramos los servicios a utilizar con Dependency Injection:
using Microsoft.Extensions.Logging;

var host = Host.CreateDefaultBuilder(args)
    .UseWindowsService(options =>
    {
        options.ServiceName = "ServiceName";
    })
    .ConfigureServices((hostContext, services) =>
    {
        services.AddHostedService<Worker>();

        services.AddTransient<IExampleOne, ExampleOne>();
        services.AddTransient<IExampleTwo, ExampleTwo>();

        services.AddLogging(logging =>
        {
            logging.AddEventLog();
        });
    })
    .Build();

host.Run();
  1. Ejemplo de implementación dentro del Worker.cs:
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
    while (!stoppingToken.IsCancellationRequested)
    {
        // TODO: Lógica en segundo plano
        await Task.Delay(5000, stoppingToken);
    }
}
  1. Agregamos <OutputType>WinExe</OutputType> en el .csproj para evitar que se abra una consola al iniciar el servicio:
<PropertyGroup>
  <TargetFramework>net8.0</TargetFramework>
  <Nullable>enable</Nullable>
  <ImplicitUsings>enable</ImplicitUsings>
  <OutputType>WinExe</OutputType> <!-- Agregar aquí -->
</PropertyGroup>
  1. Publicamos el ejecutable en modo Release:
dotnet publish -c Release -o ./publish

Esto generará la carpeta publish con los archivos necesarios para instalar el servicio en Windows.

  1. Instalamos el servicio desde PowerShell (como administrador). Se recomienda que no haya espacios en blanco dentro de la ruta del ejecutable:
New-Service -Name "ServiceName" -BinaryPathName "C:\Services\ServiceName\ServiceName.exe" -StartupType Automatic
  1. Para desinstalar el servicio:
Remove-Service -Name "ServiceName"