C#: Cómo crear un servicio con .NET 6

Algunas aplicaciones como sincronizadores o cualquier aplicación que tenga que realizar una tarea en menos de un minuto es interesante que se ejecuten mediante un servicio.

Cierto es que siempre tenemos la opción de crear una aplicación del tipo consola, sin embargo, si la queremos ejecutar en corto periodo de tiempo, es posible que se nos ejecuten varias instancias por lo que más adecuado es crear un servicio con .NET 6.

Un punto importante de .Net Core frente a .Net Framework es que el primero nos permitirá crear servicios también para sistemas Linux, por lo que ya no tendremos que recurrir a Python u otro lenguaje de programación.

Creación del proyecto Worker Service

El primer paso para crear un servicio con .NET 6 es abrir Visual Studio y crear un nuevo proyecto del tipo «Worker Service».

C#: Cómo crear un servicio con .NET 6 1

El siguiente paso sería escoger el nombre para nuestro proyecto y la ubicación donde guardarlo.

C#: Cómo crear un servicio con .NET 6 2

Para acabar de configurar nuestro proyecto escogemos como plataforma de destino .NET 6.

C#: Cómo crear un servicio con .NET 6 3

Ya tenemos creado nuestro proyecto, la clase Worker es la encargada de ejecutar la acción de nuestro servicio.

public class Worker : BackgroundService
    {
        private readonly ILogger<Worker> _logger;
        public Worker(ILogger<Worker> logger)
        {
            _logger = logger;
        }
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
                await Task.Delay(1000, stoppingToken);
            }
        }
    }

La parte que nos interesa es ExecuteAsync, es aquí donde debemos configurar las acciones que queramos que haga nuestro servicio.

En la parte del código await Task.Delay(1000, stoppingToken); le indicamos en milisegundos cuanto tiempo debe esperar entre ejecuciones, si no incluimos esta parte automáticamente cuando el método acabe se volverá a ejecutar instantáneamente. El tiempo se indica en milisegundos 1000 ms = 1 s.

Una buena práctica es no incluir directamente el código en esta clase, sino referenciar a un proyecto que contenga nuestros servicios y llamar al servicio directamente. Aunque como este artículo es un ejemplo, incluiremos el código directamente en la clase.

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                string path = @"C:\ServiceTest\";
                //Creamos el directorio
                Directory.CreateDirectory(path);
                //Establecemos la ubicación del fichero de texto
                path += "output.txt";
                //Escribimos en el fichero
                using (StreamWriter sw = File.AppendText(path))
                {
                    sw.WriteLine($"Hello world from the {DateTime.Now}");
                }
                //Se ejecutará cada 1000 ms = 1 segundo
                await Task.Delay(1000, stoppingToken);
            }
        }

Este código lo que hace básicamente es que cada segundo nos generará un archivo en C:\\service\output.txt y nos escribirá un hello world con la fecha actual cada segundo.

C#: Cómo crear un servicio con .NET 6 4

Es un servicio que realmente no hace nada útil, pero nos servirá para saber si se está ejecutando correctamente.

Instalar el servicio .NET 6 en Windows

Por defecto, .NET 6 no trae el paquete necesario para que nuestro servicio funcione sobre Windows, simplemente tenemos que agregar el siguiente paquete NuGet a nuestro proyecto:

C#: Cómo crear un servicio con .NET 6 5

Por último, tenemos que llamar al paquete que acabamos de instalar, en nuestro Program.cs, simplemente escribimos .UseWindowsService(), justo debajo del .ConfigureServices quedando el código de nuestro program así:

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace ServiceTest
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }
        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureServices((hostContext, services) =>
                {
                    services.AddHostedService<Worker>();
                })
                //Metodo que permite ejecutar el servicio en Windows. 
                .UseWindowsService();
    }
}

Para instalar el servicio compilamos nuestra aplicación en Release y copiamos los ficheros en el directorio donde queramos instalar la aplicación.

Abrimos una consola de comandos como administrador y escribimos el siguiente comando:

SC CREATE "NombreServicio" binpath="Path Al exe de nuestro servicio"
C#: Cómo crear un servicio con .NET 6 6

Si te aparece algún mensaje de acceso denegado es que no has ejecutado la consola como administrador. Si te aparece el comando como en la imagen es que se instaló correctamente y ya puedes buscarlo en el listado de servicios de Windows.

C#: Cómo crear un servicio con .NET 6 7

Si al arrancar el servicio te da un error es posible que no hayas instalado el runtime de .Net en el equipo. Puedes descargarlo desde este enlace.

Desinstalar el servicio

Para acabar el artículo, como supongo que no querrás tener un servicio que simplemente dice hola en tu equipo, debes de saber que puedes desinstalarlo escribiendo el siguiente comando en una consola de administrador.

SC DELETE "NombreServicio"

Es recomendable parar el servicio antes o seguramente deberás reiniciar.

Para crear un instalador para el servicio sigue este tutorial.

Para acabar el artículo, si estás pensando en comprar hosting o en comprar dominio Web, déjame recomendarte estos artículos:

5 comentarios en «C#: Cómo crear un servicio con .NET 6»

  1. Excelente tutorial muchas gracias, me gustaría saber si puedo crear un instalador a este tipo de servicios, no he conseguido un tutorial con dicha información, la manera que acá se muestra es muy buena, sin embargo para salir a producción y mandar a instalar el servicio en muchas maquinas de esta manera no me gustaría, agradezco su ayuda, muchas gracias

    Responder
  2. Hola buen dia, a mi no me queda clara la parte del create(SC CREATE «NombreServicio» binpath=»Path Al exe de nuestro servicio») digamos la parte del binpath como saco esa ruta?, yo la asigno para guardar ahi el exe?, como yo entiendo el .exe no existe aun no?,

    Muchas preguntas pero es que no veo que se explique sea español o ingles,
    me sale error al querer poner sc.exe start «Service» mas no con el create y no se cual es el error, ya intente quitando y poniendo comillas y separando la ruta del igual (sc.exe create «SERVprueba Service» binpath= «C:\SERVpruebaWorkerService.exe») (sc.exe start «SERVprueba Service») y no me deja iniciarlo estoy con vs code (comandos dotnet)

    Responder

Deja un comentario