Comparteix a través de


Hospedaje de ASP.NET Core en un servicio de Windows

Nota:

Esta no es la versión más reciente de este artículo. Para la versión actual, consulta la versión .NET 8 de este artículo.

Advertencia

Esta versión de ASP.NET Core ya no se admite. Para obtener más información, consulta la Directiva de soporte técnico de .NET y .NET Core. Para la versión actual, consulta la versión .NET 8 de este artículo.

Importante

Esta información hace referencia a un producto en versión preliminar, el cual puede sufrir importantes modificaciones antes de que se publique la versión comercial. Microsoft no proporciona ninguna garantía, expresa o implícita, con respecto a la información proporcionada aquí.

Para la versión actual, consulte la versión .NET 8 de este artículo.

Una aplicación de ASP.NET Core se puede hospedar en Windows sin usar IIS como servicio de Windows. Cuando se hospeda como un servicio de Windows, la aplicación se inicia automáticamente después de reiniciar el servidor.

Requisitos previos

Plantilla Worker Service

La plantilla Worker Service de ASP.NET Core sirve de punto de partida para escribir aplicaciones de servicio de larga duración. Para usar la plantilla como base de una aplicación de servicio de Windows:

  1. Cree una aplicación Worker Service con la plantilla de .NET Core.
  2. Instale el paquete NuGet Microsoft.Extensions.Hosting.WindowsServices.
  3. Siga las instrucciones de la sección Configuración de aplicaciones para actualizar la aplicación Worker Service a fin de que se ejecute como un servicio de Windows.
  1. Cree un nuevo proyecto.
  2. Seleccione Worker Service (Servicio de Worker). Seleccione Siguiente.
  3. Proporcione un nombre para el proyecto en el campo Nombre del proyecto o acepte el predeterminado. Seleccione Crear.
  4. En el cuadro de diálogo Crear un servicio de Worker, seleccione Crear.

Configuración de aplicaciones

Actualice Program.cs para llamar a AddWindowsService. Cuando la aplicación se ejecuta como un servicio de Windows, AddWindowsService:

  • Establece la vigencia del host en WindowsServiceLifetime.
  • Establece la raíz del contenido en AppContext.BaseDirectory. Para obtener más información, consulte la sección Directorio actual y raíz del contenido.
  • Habilita el registro en el registro de eventos:
    • El nombre de la aplicación se usa como nombre de origen predeterminado.
    • El nivel de registro predeterminado es Advertencia o superior para una aplicación basada en una plantilla de ASP.NET Core que llama a CreateDefaultBuilder con el fin de compilar el host.
    • Invalide el nivel de registro predeterminado con la clave Logging:EventLog:LogLevel:Default en appsettings.json/appsettings.{Environment}.json u otro proveedor de configuración.
    • Los administradores son los únicos que pueden crear nuevos orígenes de eventos. Cuando no se puede crear un origen de eventos con el nombre de la aplicación, se registra una advertencia para el origen Aplicación y los registros de eventos se deshabilitan.

Observe la clase ServiceA siguiente:

namespace SampleApp.Services;

public class ServiceA : BackgroundService
{
    public ServiceA(ILoggerFactory loggerFactory)
    {
        Logger = loggerFactory.CreateLogger<ServiceA>();
    }

    public ILogger Logger { get; }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        Logger.LogInformation("ServiceA is starting.");

        stoppingToken.Register(() => Logger.LogInformation("ServiceA is stopping."));

        while (!stoppingToken.IsCancellationRequested)
        {
            Logger.LogInformation("ServiceA is doing background work.");

            await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken);
        }

        Logger.LogInformation("ServiceA has stopped.");
    }
}

Las siguientes Program.cs llamadas a AddHostedService para registrar ServiceA:

using SampleApp.Services;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.AddWindowsService();
builder.Services.AddHostedService<ServiceA>();

var app = builder.Build();

app.MapRazorPages();

app.Run();

Las aplicaciones de ejemplo siguientes acompañan a este tema:

  • Ejemplo de Background Worker Service: un ejemplo de una aplicación que no es para la Web basado en la plantilla Worker Service que usa servicios hospedados para las tareas en segundo plano.
  • Ejemplo de App Service web: un ejemplo de aplicación web de Razor Pages que se ejecuta como un servicio de Windows con servicios hospedados para las tareas en segundo plano.

Para obtener instrucciones de MVC, vea los artículos Información general de ASP.NET Core MVC y Migración de ASP.NET Core 2.2 a 3.0.

Tipo de implementación

Para obtener información y consejos sobre los escenarios de implementación, consulte Implementación de aplicaciones .NET Core.

SDK

En el caso de un servicio basado en una aplicación web que use los marcos Razor Pages o MVC, especifique el SDK web en el archivo de proyecto:

<Project Sdk="Microsoft.NET.Sdk.Web">

Si el servicio solo ejecuta tareas en segundo plano (por ejemplo, servicios hospedados), especifique el SDK de Worker en el archivo de proyecto:

<Project Sdk="Microsoft.NET.Sdk.Worker">

Implementación dependiente de marco (FDD)

La implementación dependiente de marco de trabajo (FDD) se basa en la presencia de una versión compartida de .NET Core en todo el sistema en el sistema de destino. Cuando se adopta el escenario FDD siguiendo las instrucciones de este artículo, el SDK genera un archivo ejecutable ( .exe), denominado ejecutable dependiente del marco.

Si se usa el SDK web, para una aplicación de Windows Services no se requiere un archivo web.config, que normalmente se crea cuando se publica una aplicación ASP.NET Core. Para deshabilitar la creación de un archivo web.config agregue la propiedad <IsTransformWebConfigDisabled> establecida en true.

<PropertyGroup>
  <TargetFramework>net7.0</TargetFramework>
  <IsTransformWebConfigDisabled>true</IsTransformWebConfigDisabled>
</PropertyGroup>

Implementación autocontenida (SCD)

Una implementación autocontenida (SCD) no depende de la presencia de un marco compartido en el sistema host. El tiempo de ejecución y las dependencias de la aplicación se implementan con la aplicación.

Un identificador en tiempo de ejecución (RID) se incluye en el <PropertyGroup> que contiene la plataforma de destino:

<RuntimeIdentifier>win-x64</RuntimeIdentifier>

Para publicar para varios RID:

  • Proporcione los RID en una lista delimitada por punto y coma.
  • Utilice el nombre de propiedad <RuntimeIdentifiers> (en plural).

Para más información, vea el Catálogo de identificadores de entorno de ejecución (RID) de .NET Core.

Cuenta de usuario de servicio

Para crear una cuenta de usuario para un servicio, use el cmdlet New-LocalUser de un shell de comandos administrativos de PowerShell 6.

En la actualización de octubre de 2018 de Windows 10 (versión 1809/compilación 10.0.17763) o posterior:

New-LocalUser -Name {SERVICE NAME}

En el sistema operativo Windows anterior a la actualización de octubre de 2018 de Windows 10 (versión 1809/compilación 10.0.17763):

powershell -Command "New-LocalUser -Name {SERVICE NAME}"

Proporcione una contraseña segura cuando se le solicite.

A menos que el parámetro -AccountExpires se proporcione para el cmdlet New-LocalUser con una fecha de expiración DateTime, la cuenta no expirará.

Para más información, vea Microsoft.PowerShell.LocalAccounts y Service User Accounts (Cuentas de usuario del servicio).

Un enfoque alternativo de administración de usuarios al usar Active Directory consiste en usar cuentas de servicio administradas. Para obtener más información, consulte grupo Managed Service Accounts Overview (Información general sobre cuentas de servicio administradas de grupo).

Derechos para iniciar sesión como servicio

Para establecer los derechos de Iniciar sesión como servicio para una cuenta de usuario del servicio:

  1. Abra el editor de la Directiva de seguridad local mediante la ejecución de secpol.msc.
  2. Expanda el nodo Directivas locales y, después, seleccione Asignación de derechos de usuario.
  3. Abra la directiva Iniciar sesión como servicio.
  4. Seleccione Agregar usuario o grupo.
  5. Proporcione el nombre de objeto (cuenta de usuario) mediante cualquiera de los métodos siguientes:
    1. Escriba la cuenta de usuario ({DOMAIN OR COMPUTER NAME\USER}) en el campo del nombre de objeto y seleccione Aceptar para agregar el usuario a la directiva.
    2. Seleccione Opciones avanzadas. Seleccione Buscar ahora. Seleccione la cuenta de usuario de la lista. Seleccione Aceptar. Seleccione Aceptar nuevo para agregar el usuario a la directiva.
  6. Seleccione Aceptar o Aplicar para aceptar los cambios.

Creación y administración del servicio de Windows

Creación de un servicio

Use los comandos de PowerShell para registrar un servicio. Desde un shell de comandos administrativos de PowerShell 6, ejecute los comandos siguientes:

$acl = Get-Acl "{EXE PATH}"
$aclRuleArgs = "{DOMAIN OR COMPUTER NAME\USER}", "Read,Write,ReadAndExecute", "ContainerInherit,ObjectInherit", "None", "Allow"
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($aclRuleArgs)
$acl.SetAccessRule($accessRule)
$acl | Set-Acl "{EXE PATH}"

New-Service -Name {SERVICE NAME} -BinaryPathName "{EXE FILE PATH} --contentRoot {EXE FOLDER PATH}" -Credential "{DOMAIN OR COMPUTER NAME\USER}" -Description "{DESCRIPTION}" -DisplayName "{DISPLAY NAME}" -StartupType Automatic
  • {EXE PATH}: ruta de acceso del ejecutable de la aplicación en el host (por ejemplo, d:\myservice). No incluya el archivo ejecutable de la aplicación en la ruta de acceso. No se requiere una barra diagonal al final.
  • {DOMAIN OR COMPUTER NAME\USER}: cuenta de usuario de servicio (por ejemplo, Contoso\ServiceUser).
  • {SERVICE NAME}: nombre de servicio (por ejemplo, MyService).
  • {EXE FILE PATH}: ruta de acceso ejecutable completa de la aplicación (por ejemplo, d:\myservice\myservice.exe). Incluya el nombre de archivo del ejecutable con la extensión.
  • {EXE FOLDER PATH}: ruta de acceso completa a la carpeta ejecutable (por ejemplo, d:\myservice).
  • {DESCRIPTION}: descripción del servicio (por ejemplo, My sample service).
  • {DISPLAY NAME}: nombre para mostrar del servicio (por ejemplo, My Service).

iniciar un servicio.

Inicie el servicio con el siguiente comando de PowerShell 6:

Start-Service -Name {SERVICE NAME}

Este comando tarda unos segundos en iniciar el servicio.

Determinación del estado de un servicio

Para comprobar el estado de un servicio, use el siguiente comando de PowerShell 6:

Get-Service -Name {SERVICE NAME}

El estado se notifica como uno de los siguientes valores:

  • Starting
  • Running
  • Stopping
  • Stopped

Detención de un servicio

Detenga un servicio con el siguiente comando de PowerShell 6:

Stop-Service -Name {SERVICE NAME}

Eliminación de un servicio

Tras un breve intervalo para detener un servicio, elimine el servicio con el siguiente comando de PowerShell 6:

Remove-Service -Name {SERVICE NAME}

Escenarios de servidor proxy y equilibrador de carga

Los servicios que interactúan con las solicitudes de Internet o de una red corporativa y están detrás de un proxy o de un equilibrador de carga podrían requerir configuración adicional. Para obtener más información, consulte Configuración de ASP.NET Core para trabajar con servidores proxy y equilibradores de carga.

Configuración de puntos de conexión

ASP.NET Core se enlaza a http://localhost:5000 de forma predeterminada. Configure la dirección URL y el puerto estableciendo la variable de entorno ASPNETCORE_URLS.

Para información sobre otros enfoques de configuración de direcciones URL y puertos, consulte el artículo en cuestión:

En la guía anterior se trata la compatibilidad con los puntos de conexión HTTPS. Por ejemplo, configure la aplicación para HTTPS cuando se use la autenticación con un servicio de Windows.

Nota

No se admite el uso del certificado de desarrollo HTTPS de ASP.NET Core para proteger un punto de conexión de servicio.

Directorio actual y raíz del contenido

El directorio de trabajo actual devuelto por una llamada a GetCurrentDirectory para un servicio de Windows es la carpeta C:\WINDOWS\system32. La carpeta system32 no es una ubicación adecuada para almacenar los archivos de un servicio (por ejemplo los archivos de configuración). Utilice uno de los siguientes enfoques para mantener los archivos de configuración y los activos de un servicio, así como para acceder a ellos.

Uso de ContentRootPath o ContentRootFileProvider

Use IHostEnvironment.ContentRootPath o ContentRootFileProvider para buscar los recursos de una aplicación.

Cuando la aplicación se ejecuta como un servicio, UseWindowsService establece la ruta de acceso ContentRootPath en AppContext.BaseDirectory.

Los archivos de configuración predeterminados de la aplicación, appsettings.jsony appsettings.{Environment}.json, se cargan desde la raíz del contenido de la aplicación mediante una llamada a CreateDefaultBuilder durante la construcción del host.

En el caso de otros archivos de configuración cargados por el código para desarrolladores en ConfigureAppConfiguration, no es necesario llamar a SetBasePath. En el ejemplo siguiente, el archivo custom_settings.json ya se encuentra en la raíz del contenido de la aplicación y se carga sin establecer explícitamente una ruta de acceso base:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .UseWindowsService()
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddJsonFile("custom_settings.json");
            })
            .ConfigureServices((hostContext, services) =>
            {
                services.AddHostedService<Worker>();
            });
}

No intente usar GetCurrentDirectory para obtener una ruta de acceso a recursos porque una aplicación de servicio de Windows devuelve la carpeta C:\WINDOWS\system32 como su directorio actual.

Almacenamiento de los archivos de un servicio en una ubicación adecuada en el disco

Especifique una ruta de acceso absoluta con SetBasePath al utilizar un IConfigurationBuilder a la carpeta que contiene los archivos.

Solucionar problemas

Para solucionar problemas de una aplicación de servicio de Windows, vea Solución de problemas y depuración de proyectos de ASP.NET Core.

Errores comunes

  • Se está usando una versión preliminar o antigua de PowerShell.
  • El servicio registrado no usa la salida publicada de la aplicación del comando dotnet publish. La salida del comando dotnet build no es compatible con la implementación de aplicaciones. Los recursos publicados se encuentran en cualquiera de las siguientes carpetas, según el tipo de implementación:
    • bin/Release/{PLATAFORMA DE DESTINO}/publish (FDD)
    • bin/Release/{PLATAFORMA DE DESTINO}/{IDENTIFICADOR DE RUNTIME}/publish (SCD)
  • El servicio no está en el estado EN EJECUCIÓN.
  • Las rutas de acceso a los recursos que usa la aplicación (por ejemplo, certificados) son incorrectas. La ruta de acceso base de un servicio de Windows es c:\Windows\System32.
  • El usuario no tiene derechos de inicio de sesión como servicio.
  • La contraseña del usuario ha expirado o se ha pasado incorrectamente al ejecutar el comando de PowerShell New-Service.
  • La aplicación requiere autenticación ASP.NET Core, pero no está configurada para conexiones seguras (HTTPS).
  • El puerto de la dirección URL de solicitud es incorrecto o no está configurado correctamente en la aplicación.

Registros de eventos del sistema y de aplicación

Acceda a los registros de eventos del sistema y de aplicación:

  1. Abra el menú Inicio, busque Visor de eventos y seleccione la aplicación Visor de eventos.
  2. En Visor de eventos, abra el nodo Registros de Windows.
  3. Seleccione Sistema para abrir el registro de eventos del sistema. Seleccione Aplicación para abrir el registro de eventos de la aplicación.
  4. Busque los errores asociados a la aplicación objeto del error.

Ejecución de la aplicación en un símbolo del sistema

Muchos errores de inicio no generan información útil en el registro de eventos. La causa de algunos errores se puede encontrar mediante la ejecución de la aplicación en un símbolo del sistema en el sistema de hospedaje. Para registrar detalles adicionales de la aplicación, reduzca el nivel de registro o ejecute la aplicación en el entorno de desarrollo.

Borrado de memorias caché de paquetes

Una aplicación en funcionamiento deja de ejecutarse inmediatamente después de actualizar el SDK de .NET Core en la máquina de desarrollo o de cambiar las versiones del paquete en la aplicación. En algunos casos, los paquetes incoherentes pueden interrumpir una aplicación al realizar actualizaciones importantes. La mayoría de estos problemas puede corregirse siguiendo estas instrucciones:

  1. Elimine las carpetas bin y obj.

  2. Borre las memorias caché del paquete ejecutando dotnet nuget locals all --clear desde un shell de comandos.

    Otra manera de borrar las memorias caché de paquetes es usando la herramienta nuget.exe y ejecutando el comando nuget locals all -clear. nuget.exe no es una instalación agrupada con el sistema operativo de escritorio de Windows y se debe obtener de forma independiente en el sitio web de NuGet.

  3. Restaure el proyecto y vuelva a compilarlo.

  4. Elimine todos los archivos de la carpeta de implementación del servidor antes de volver a implementar la aplicación.

Aplicación lenta o sin respuesta

Un volcado de memoria es una instantánea de la memoria del sistema que puede ayudar a determinar la causa de un bloqueo de la aplicación, un error de inicio o una aplicación lenta.

Bloqueo o excepción de la aplicación

Obtenga y analice un volcado de memoria en Informe de errores de Windows (WER):

  1. Cree una carpeta para almacenar los archivos de volcado de memoria en c:\dumps.

  2. Ejecute el script EnableDumps PowerShell con el nombre del archivo ejecutable de la aplicación:

    .\EnableDumps {APPLICATION EXE} c:\dumps
    
  3. Ejecute la aplicación en las condiciones que hacen que se produzca el bloqueo.

  4. Una vez que se haya producido el bloqueo, ejecute el script DisableDumps de PowerShell:

    .\DisableDumps {APPLICATION EXE}
    

Después de que se bloquee la aplicación y se complete la recopilación del volcado de memoria, la aplicación puede finalizar con normalidad. El script de PowerShell configura WER de modo que recopile un máximo de cinco volcados de memoria por aplicación.

Advertencia

Los volcados de memoria pueden ocupar una gran cantidad de espacio en disco (hasta varios gigabytes cada uno).

La aplicación deja de responder, produce un error durante el inicio o se ejecuta con normalidad

Si una aplicación deja de responder pero no se bloquea, produce un error durante el inicio o se ejecuta con normalidad, consulta User-Mode Dump Files: Choosing the Best Tool para seleccionar una herramienta apropiada para generar el volcado de memoria:

Análisis del volcado de memoria

El volcado de memoria se puede analizar de varias maneras. Para obtener más información, vea Analyzing a User-Mode Dump File (Análisis de un archivo de volcado de memoria en modo de usuario).

Recursos adicionales

Una aplicación de ASP.NET Core se puede hospedar en Windows sin usar IIS como servicio de Windows. Cuando se hospeda como un servicio de Windows, la aplicación se inicia automáticamente después de reiniciar el servidor.

Vea o descargue el código de ejemplo (cómo descargarlo)

Requisitos previos

Plantilla Worker Service

La plantilla Worker Service de ASP.NET Core sirve de punto de partida para escribir aplicaciones de servicio de larga duración. Para usar la plantilla como base de una aplicación de servicio de Windows:

  1. Cree una aplicación Worker Service con la plantilla de .NET Core.
  2. Siga las instrucciones de la sección Configuración de aplicaciones para actualizar la aplicación Worker Service a fin de que se ejecute como un servicio de Windows.
  1. Cree un nuevo proyecto.
  2. Seleccione Worker Service (Servicio de Worker). Seleccione Siguiente.
  3. Proporcione un nombre para el proyecto en el campo Nombre del proyecto o acepte el predeterminado. Seleccione Crear.
  4. En el cuadro de diálogo Crear un servicio de Worker, seleccione Crear.

Configuración de aplicaciones

La aplicación requiere una referencia de paquete para Microsoft.Extensions.Hosting.WindowsServices.

Se llama a IHostBuilder.UseWindowsService al compilar el host. Si la aplicación se ejecuta como un servicio de Windows, el método:

  • Establece la vigencia del host en WindowsServiceLifetime.
  • Establece la raíz del contenido en AppContext.BaseDirectory. Para obtener más información, consulte la sección Directorio actual y raíz del contenido.
  • Habilita el registro en el registro de eventos:
    • El nombre de la aplicación se usa como nombre de origen predeterminado.
    • El nivel de registro predeterminado es Advertencia o superior para una aplicación basada en una plantilla de ASP.NET Core que llama a CreateDefaultBuilder con el fin de compilar el host.
    • Invalide el nivel de registro predeterminado con la clave Logging:EventLog:LogLevel:Default en appsettings.json/appsettings.{Environment}.json u otro proveedor de configuración.
    • Los administradores son los únicos que pueden crear nuevos orígenes de eventos. Cuando no se puede crear un origen de eventos con el nombre de la aplicación, se registra una advertencia para el origen Aplicación y los registros de eventos se deshabilitan.

En Program.cs:

  • EstablezcaContentRootPath.
  • Llame a UseWindowsService
using Microsoft.Extensions.Hosting.WindowsServices;
using SampleApp.Services;

var options = new WebApplicationOptions
{
    Args = args,
    ContentRootPath = WindowsServiceHelpers.IsWindowsService() 
                                     ? AppContext.BaseDirectory : default
};

var builder = WebApplication.CreateBuilder(options);
builder.Services.AddRazorPages();
builder.Services.AddHostedService<ServiceA>();
builder.Services.AddHostedService<ServiceB>();

builder.Host.UseWindowsService();

var app = builder.Build();

app.UseStaticFiles();
app.UseRouting();
app.MapRazorPages();
await app.RunAsync();

Las aplicaciones de ejemplo siguientes acompañan a este tema:

  • Ejemplo de Background Worker Service: un ejemplo de una aplicación que no es para la Web basado en la plantilla Worker Service que usa servicios hospedados para las tareas en segundo plano.
  • Ejemplo de App Service web: un ejemplo de aplicación web de Razor Pages que se ejecuta como un servicio de Windows con servicios hospedados para las tareas en segundo plano.

Para obtener instrucciones de MVC, vea los artículos Información general de ASP.NET Core MVC y Migración de ASP.NET Core 2.2 a 3.0.

Tipo de implementación

Para obtener información y consejos sobre los escenarios de implementación, consulte Implementación de aplicaciones .NET Core.

SDK

En el caso de un servicio basado en una aplicación web que use los marcos Razor Pages o MVC, especifique el SDK web en el archivo de proyecto:

<Project Sdk="Microsoft.NET.Sdk.Web">

Si el servicio solo ejecuta tareas en segundo plano (por ejemplo, servicios hospedados), especifique el SDK de Worker en el archivo de proyecto:

<Project Sdk="Microsoft.NET.Sdk.Worker">

Implementación dependiente de marco (FDD)

La implementación dependiente de marco de trabajo (FDD) se basa en la presencia de una versión compartida de .NET Core en todo el sistema en el sistema de destino. Cuando se adopta el escenario FDD siguiendo las instrucciones de este artículo, el SDK genera un archivo ejecutable ( .exe), denominado ejecutable dependiente del marco.

Si se usa el SDK web, para una aplicación de Windows Services no se requiere un archivo web.config, que normalmente se crea cuando se publica una aplicación ASP.NET Core. Para deshabilitar la creación de un archivo web.config agregue la propiedad <IsTransformWebConfigDisabled> establecida en true.

<PropertyGroup>
  <TargetFramework>net6.0</TargetFramework>
  <IsTransformWebConfigDisabled>true</IsTransformWebConfigDisabled>
</PropertyGroup>

Implementación autocontenida (SCD)

Una implementación autocontenida (SCD) no depende de la presencia de un marco compartido en el sistema host. El tiempo de ejecución y las dependencias de la aplicación se implementan con la aplicación.

Un identificador en tiempo de ejecución (RID) se incluye en el <PropertyGroup> que contiene la plataforma de destino:

<RuntimeIdentifier>win7-x64</RuntimeIdentifier>

Para publicar para varios RID:

  • Proporcione los RID en una lista delimitada por punto y coma.
  • Utilice el nombre de propiedad <RuntimeIdentifiers> (en plural).

Para más información, vea el Catálogo de identificadores de entorno de ejecución (RID) de .NET Core.

Cuenta de usuario de servicio

Para crear una cuenta de usuario para un servicio, use el cmdlet New-LocalUser de un shell de comandos administrativos de PowerShell 6.

En la actualización de octubre de 2018 de Windows 10 (versión 1809/compilación 10.0.17763) o posterior:

New-LocalUser -Name {SERVICE NAME}

En el sistema operativo Windows anterior a la actualización de octubre de 2018 de Windows 10 (versión 1809/compilación 10.0.17763):

powershell -Command "New-LocalUser -Name {SERVICE NAME}"

Proporcione una contraseña segura cuando se le solicite.

A menos que el parámetro -AccountExpires se proporcione para el cmdlet New-LocalUser con una fecha de expiración DateTime, la cuenta no expirará.

Para más información, vea Microsoft.PowerShell.LocalAccounts y Service User Accounts (Cuentas de usuario del servicio).

Un enfoque alternativo de administración de usuarios al usar Active Directory consiste en usar cuentas de servicio administradas. Para obtener más información, consulte grupo Managed Service Accounts Overview (Información general sobre cuentas de servicio administradas de grupo).

Derechos para iniciar sesión como servicio

Para establecer los derechos de Iniciar sesión como servicio para una cuenta de usuario del servicio:

  1. Abra el editor de la Directiva de seguridad local mediante la ejecución de secpol.msc.
  2. Expanda el nodo Directivas locales y, después, seleccione Asignación de derechos de usuario.
  3. Abra la directiva Iniciar sesión como servicio.
  4. Seleccione Agregar usuario o grupo.
  5. Proporcione el nombre de objeto (cuenta de usuario) mediante cualquiera de los métodos siguientes:
    1. Escriba la cuenta de usuario ({DOMAIN OR COMPUTER NAME\USER}) en el campo del nombre de objeto y seleccione Aceptar para agregar el usuario a la directiva.
    2. Seleccione Opciones avanzadas. Seleccione Buscar ahora. Seleccione la cuenta de usuario de la lista. Seleccione Aceptar. Seleccione Aceptar nuevo para agregar el usuario a la directiva.
  6. Seleccione Aceptar o Aplicar para aceptar los cambios.

Creación y administración del servicio de Windows

Creación de un servicio

Use los comandos de PowerShell para registrar un servicio. Desde un shell de comandos administrativos de PowerShell 6, ejecute los comandos siguientes:

$acl = Get-Acl "{EXE PATH}"
$aclRuleArgs = "{DOMAIN OR COMPUTER NAME\USER}", "Read,Write,ReadAndExecute", "ContainerInherit,ObjectInherit", "None", "Allow"
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($aclRuleArgs)
$acl.SetAccessRule($accessRule)
$acl | Set-Acl "{EXE PATH}"

New-Service -Name {SERVICE NAME} -BinaryPathName "{EXE FILE PATH} --contentRoot {EXE FOLDER PATH}" -Credential "{DOMAIN OR COMPUTER NAME\USER}" -Description "{DESCRIPTION}" -DisplayName "{DISPLAY NAME}" -StartupType Automatic
  • {EXE PATH}: ruta de acceso del ejecutable de la aplicación en el host (por ejemplo, d:\myservice). No incluya el archivo ejecutable de la aplicación en la ruta de acceso. No se requiere una barra diagonal al final.
  • {DOMAIN OR COMPUTER NAME\USER}: cuenta de usuario de servicio (por ejemplo, Contoso\ServiceUser).
  • {SERVICE NAME}: nombre de servicio (por ejemplo, MyService).
  • {EXE FILE PATH}: ruta de acceso ejecutable completa de la aplicación (por ejemplo, d:\myservice\myservice.exe). Incluya el nombre de archivo del ejecutable con la extensión.
  • {EXE FOLDER PATH}: ruta de acceso completa a la carpeta ejecutable (por ejemplo, d:\myservice).
  • {DESCRIPTION}: descripción del servicio (por ejemplo, My sample service).
  • {DISPLAY NAME}: nombre para mostrar del servicio (por ejemplo, My Service).

iniciar un servicio.

Inicie el servicio con el siguiente comando de PowerShell 6:

Start-Service -Name {SERVICE NAME}

Este comando tarda unos segundos en iniciar el servicio.

Determinación del estado de un servicio

Para comprobar el estado de un servicio, use el siguiente comando de PowerShell 6:

Get-Service -Name {SERVICE NAME}

El estado se notifica como uno de los siguientes valores:

  • Starting
  • Running
  • Stopping
  • Stopped

Detención de un servicio

Detenga un servicio con el siguiente comando de PowerShell 6:

Stop-Service -Name {SERVICE NAME}

Eliminación de un servicio

Tras un breve intervalo para detener un servicio, elimine el servicio con el siguiente comando de PowerShell 6:

Remove-Service -Name {SERVICE NAME}

Escenarios de servidor proxy y equilibrador de carga

Los servicios que interactúan con las solicitudes de Internet o de una red corporativa y están detrás de un proxy o de un equilibrador de carga podrían requerir configuración adicional. Para obtener más información, consulte Configuración de ASP.NET Core para trabajar con servidores proxy y equilibradores de carga.

Configuración de puntos de conexión

ASP.NET Core se enlaza a http://localhost:5000 de forma predeterminada. Configure la dirección URL y el puerto estableciendo la variable de entorno ASPNETCORE_URLS.

Para información sobre otros enfoques de configuración de direcciones URL y puertos, consulte el artículo en cuestión:

En la guía anterior se trata la compatibilidad con los puntos de conexión HTTPS. Por ejemplo, configure la aplicación para HTTPS cuando se use la autenticación con un servicio de Windows.

Nota

No se admite el uso del certificado de desarrollo HTTPS de ASP.NET Core para proteger un punto de conexión de servicio.

Directorio actual y raíz del contenido

El directorio de trabajo actual devuelto por una llamada a GetCurrentDirectory para un servicio de Windows es la carpeta C:\WINDOWS\system32. La carpeta system32 no es una ubicación adecuada para almacenar los archivos de un servicio (por ejemplo los archivos de configuración). Utilice uno de los siguientes enfoques para mantener los archivos de configuración y los activos de un servicio, así como para acceder a ellos.

Uso de ContentRootPath o ContentRootFileProvider

Use IHostEnvironment.ContentRootPath o ContentRootFileProvider para buscar los recursos de una aplicación.

Cuando la aplicación se ejecuta como un servicio, UseWindowsService establece la ruta de acceso ContentRootPath en AppContext.BaseDirectory.

Los archivos de configuración predeterminados de la aplicación, appsettings.jsony appsettings.{Environment}.json, se cargan desde la raíz del contenido de la aplicación mediante una llamada a CreateDefaultBuilder durante la construcción del host.

En el caso de otros archivos de configuración cargados por el código para desarrolladores en ConfigureAppConfiguration, no es necesario llamar a SetBasePath. En el ejemplo siguiente, el archivo custom_settings.json ya se encuentra en la raíz del contenido de la aplicación y se carga sin establecer explícitamente una ruta de acceso base:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .UseWindowsService()
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddJsonFile("custom_settings.json");
            })
            .ConfigureServices((hostContext, services) =>
            {
                services.AddHostedService<Worker>();
            });
}

No intente usar GetCurrentDirectory para obtener una ruta de acceso a recursos porque una aplicación de servicio de Windows devuelve la carpeta C:\WINDOWS\system32 como su directorio actual.

Almacenamiento de los archivos de un servicio en una ubicación adecuada en el disco

Especifique una ruta de acceso absoluta con SetBasePath al utilizar un IConfigurationBuilder a la carpeta que contiene los archivos.

Solucionar problemas

Para solucionar problemas de una aplicación de servicio de Windows, vea Solución de problemas y depuración de proyectos de ASP.NET Core.

Errores comunes

  • Se está usando una versión preliminar o antigua de PowerShell.
  • El servicio registrado no usa la salida publicada de la aplicación del comando dotnet publish. La salida del comando dotnet build no es compatible con la implementación de aplicaciones. Los recursos publicados se encuentran en cualquiera de las siguientes carpetas, según el tipo de implementación:
    • bin/Release/{PLATAFORMA DE DESTINO}/publish (FDD)
    • bin/Release/{PLATAFORMA DE DESTINO}/{IDENTIFICADOR DE RUNTIME}/publish (SCD)
  • El servicio no está en el estado EN EJECUCIÓN.
  • Las rutas de acceso a los recursos que usa la aplicación (por ejemplo, certificados) son incorrectas. La ruta de acceso base de un servicio de Windows es c:\Windows\System32.
  • El usuario no tiene derechos de inicio de sesión como servicio.
  • La contraseña del usuario ha expirado o se ha pasado incorrectamente al ejecutar el comando de PowerShell New-Service.
  • La aplicación requiere autenticación ASP.NET Core, pero no está configurada para conexiones seguras (HTTPS).
  • El puerto de la dirección URL de solicitud es incorrecto o no está configurado correctamente en la aplicación.

Registros de eventos del sistema y de aplicación

Acceda a los registros de eventos del sistema y de aplicación:

  1. Abra el menú Inicio, busque Visor de eventos y seleccione la aplicación Visor de eventos.
  2. En Visor de eventos, abra el nodo Registros de Windows.
  3. Seleccione Sistema para abrir el registro de eventos del sistema. Seleccione Aplicación para abrir el registro de eventos de la aplicación.
  4. Busque los errores asociados a la aplicación objeto del error.

Ejecución de la aplicación en un símbolo del sistema

Muchos errores de inicio no generan información útil en el registro de eventos. La causa de algunos errores se puede encontrar mediante la ejecución de la aplicación en un símbolo del sistema en el sistema de hospedaje. Para registrar detalles adicionales de la aplicación, reduzca el nivel de registro o ejecute la aplicación en el entorno de desarrollo.

Borrado de memorias caché de paquetes

Una aplicación en funcionamiento deja de ejecutarse inmediatamente después de actualizar el SDK de .NET Core en la máquina de desarrollo o de cambiar las versiones del paquete en la aplicación. En algunos casos, los paquetes incoherentes pueden interrumpir una aplicación al realizar actualizaciones importantes. La mayoría de estos problemas puede corregirse siguiendo estas instrucciones:

  1. Elimine las carpetas bin y obj.

  2. Borre las memorias caché del paquete ejecutando dotnet nuget locals all --clear desde un shell de comandos.

    Otra manera de borrar las memorias caché de paquetes es usando la herramienta nuget.exe y ejecutando el comando nuget locals all -clear. nuget.exe no es una instalación agrupada con el sistema operativo de escritorio de Windows y se debe obtener de forma independiente en el sitio web de NuGet.

  3. Restaure el proyecto y vuelva a compilarlo.

  4. Elimine todos los archivos de la carpeta de implementación del servidor antes de volver a implementar la aplicación.

Aplicación lenta o sin respuesta

Un volcado de memoria es una instantánea de la memoria del sistema que puede ayudar a determinar la causa de un bloqueo de la aplicación, un error de inicio o una aplicación lenta.

Bloqueo o excepción de la aplicación

Obtenga y analice un volcado de memoria en Informe de errores de Windows (WER):

  1. Cree una carpeta para almacenar los archivos de volcado de memoria en c:\dumps.

  2. Ejecute el script EnableDumps PowerShell con el nombre del archivo ejecutable de la aplicación:

    .\EnableDumps {APPLICATION EXE} c:\dumps
    
  3. Ejecute la aplicación en las condiciones que hacen que se produzca el bloqueo.

  4. Una vez que se haya producido el bloqueo, ejecute el script DisableDumps de PowerShell:

    .\DisableDumps {APPLICATION EXE}
    

Después de que se bloquee la aplicación y se complete la recopilación del volcado de memoria, la aplicación puede finalizar con normalidad. El script de PowerShell configura WER de modo que recopile un máximo de cinco volcados de memoria por aplicación.

Advertencia

Los volcados de memoria pueden ocupar una gran cantidad de espacio en disco (hasta varios gigabytes cada uno).

La aplicación deja de responder, produce un error durante el inicio o se ejecuta con normalidad

Si una aplicación deja de responder pero no se bloquea, produce un error durante el inicio o se ejecuta con normalidad, consulta User-Mode Dump Files: Choosing the Best Tool para seleccionar una herramienta apropiada para generar el volcado de memoria:

Análisis del volcado de memoria

El volcado de memoria se puede analizar de varias maneras. Para obtener más información, vea Analyzing a User-Mode Dump File (Análisis de un archivo de volcado de memoria en modo de usuario).

Recursos adicionales

Una aplicación de ASP.NET Core se puede hospedar en Windows sin usar IIS como servicio de Windows. Cuando se hospeda como un servicio de Windows, la aplicación se inicia automáticamente después de reiniciar el servidor.

Vea o descargue el código de ejemplo (cómo descargarlo)

Requisitos previos

Plantilla Worker Service

La plantilla Worker Service de ASP.NET Core sirve de punto de partida para escribir aplicaciones de servicio de larga duración. Para usar la plantilla como base de una aplicación de servicio de Windows:

  1. Cree una aplicación Worker Service con la plantilla de .NET Core.
  2. Siga las instrucciones de la sección Configuración de aplicaciones para actualizar la aplicación Worker Service a fin de que se ejecute como un servicio de Windows.
  1. Cree un nuevo proyecto.
  2. Seleccione Worker Service (Servicio de Worker). Seleccione Siguiente.
  3. Proporcione un nombre para el proyecto en el campo Nombre del proyecto o acepte el predeterminado. Seleccione Crear.
  4. En el cuadro de diálogo Crear un servicio de Worker, seleccione Crear.

Configuración de aplicaciones

La aplicación requiere una referencia de paquete para Microsoft.Extensions.Hosting.WindowsServices.

Se llama a IHostBuilder.UseWindowsService al compilar el host. Si la aplicación se ejecuta como un servicio de Windows, el método:

  • Establece la vigencia del host en WindowsServiceLifetime.
  • Establece la raíz del contenido en AppContext.BaseDirectory. Para obtener más información, consulte la sección Directorio actual y raíz del contenido.
  • Habilita el registro en el registro de eventos:
    • El nombre de la aplicación se usa como nombre de origen predeterminado.
    • El nivel de registro predeterminado es Advertencia o superior para una aplicación basada en una plantilla de ASP.NET Core que llama a CreateDefaultBuilder con el fin de compilar el host.
    • Invalide el nivel de registro predeterminado con la clave Logging:EventLog:LogLevel:Default en appsettings.json/appsettings.{Environment}.json u otro proveedor de configuración.
    • Los administradores son los únicos que pueden crear nuevos orígenes de eventos. Cuando no se puede crear un origen de eventos con el nombre de la aplicación, se registra una advertencia para el origen Aplicación y los registros de eventos se deshabilitan.

En CreateHostBuilder de Program.cs:

Host.CreateDefaultBuilder(args)
    .UseWindowsService()
    ...

Las aplicaciones de ejemplo siguientes acompañan a este tema:

  • Ejemplo de Background Worker Service: un ejemplo de una aplicación que no es para la Web basado en la plantilla Worker Service que usa servicios hospedados para las tareas en segundo plano.
  • Ejemplo de App Service web: un ejemplo de aplicación web de Razor Pages que se ejecuta como un servicio de Windows con servicios hospedados para las tareas en segundo plano.

Para obtener instrucciones de MVC, vea los artículos Información general de ASP.NET Core MVC y Migración de ASP.NET Core 2.2 a 3.0.

Tipo de implementación

Para obtener información y consejos sobre los escenarios de implementación, consulte Implementación de aplicaciones .NET Core.

SDK

En el caso de un servicio basado en una aplicación web que use los marcos Razor Pages o MVC, especifique el SDK web en el archivo de proyecto:

<Project Sdk="Microsoft.NET.Sdk.Web">

Si el servicio solo ejecuta tareas en segundo plano (por ejemplo, servicios hospedados), especifique el SDK de Worker en el archivo de proyecto:

<Project Sdk="Microsoft.NET.Sdk.Worker">

Implementación dependiente de marco (FDD)

La implementación dependiente de marco de trabajo (FDD) se basa en la presencia de una versión compartida de .NET Core en todo el sistema en el sistema de destino. Cuando se adopta el escenario FDD siguiendo las instrucciones de este artículo, el SDK genera un archivo ejecutable ( .exe), denominado ejecutable dependiente del marco.

Si se usa el SDK web, para una aplicación de Windows Services no se requiere un archivo web.config, que normalmente se crea cuando se publica una aplicación ASP.NET Core. Para deshabilitar la creación de un archivo web.config agregue la propiedad <IsTransformWebConfigDisabled> establecida en true.

<PropertyGroup>
  <TargetFramework>netcoreapp3.0</TargetFramework>
  <IsTransformWebConfigDisabled>true</IsTransformWebConfigDisabled>
</PropertyGroup>

Implementación autocontenida (SCD)

Una implementación autocontenida (SCD) no depende de la presencia de un marco compartido en el sistema host. El tiempo de ejecución y las dependencias de la aplicación se implementan con la aplicación.

Un identificador en tiempo de ejecución (RID) se incluye en el <PropertyGroup> que contiene la plataforma de destino:

<RuntimeIdentifier>win7-x64</RuntimeIdentifier>

Para publicar para varios RID:

  • Proporcione los RID en una lista delimitada por punto y coma.
  • Utilice el nombre de propiedad <RuntimeIdentifiers> (en plural).

Para más información, vea el Catálogo de identificadores de entorno de ejecución (RID) de .NET Core.

Cuenta de usuario de servicio

Para crear una cuenta de usuario para un servicio, use el cmdlet New-LocalUser de un shell de comandos administrativos de PowerShell 6.

En la actualización de octubre de 2018 de Windows 10 (versión 1809/compilación 10.0.17763) o posterior:

New-LocalUser -Name {SERVICE NAME}

En el sistema operativo Windows anterior a la actualización de octubre de 2018 de Windows 10 (versión 1809/compilación 10.0.17763):

powershell -Command "New-LocalUser -Name {SERVICE NAME}"

Proporcione una contraseña segura cuando se le solicite.

A menos que el parámetro -AccountExpires se proporcione para el cmdlet New-LocalUser con una fecha de expiración DateTime, la cuenta no expirará.

Para más información, vea Microsoft.PowerShell.LocalAccounts y Service User Accounts (Cuentas de usuario del servicio).

Un enfoque alternativo de administración de usuarios al usar Active Directory consiste en usar cuentas de servicio administradas. Para obtener más información, consulte grupo Managed Service Accounts Overview (Información general sobre cuentas de servicio administradas de grupo).

Derechos para iniciar sesión como servicio

Para establecer los derechos de Iniciar sesión como servicio para una cuenta de usuario del servicio:

  1. Abra el editor de la Directiva de seguridad local mediante la ejecución de secpol.msc.
  2. Expanda el nodo Directivas locales y, después, seleccione Asignación de derechos de usuario.
  3. Abra la directiva Iniciar sesión como servicio.
  4. Seleccione Agregar usuario o grupo.
  5. Proporcione el nombre de objeto (cuenta de usuario) mediante cualquiera de los métodos siguientes:
    1. Escriba la cuenta de usuario ({DOMAIN OR COMPUTER NAME\USER}) en el campo del nombre de objeto y seleccione Aceptar para agregar el usuario a la directiva.
    2. Seleccione Opciones avanzadas. Seleccione Buscar ahora. Seleccione la cuenta de usuario de la lista. Seleccione Aceptar. Seleccione Aceptar nuevo para agregar el usuario a la directiva.
  6. Seleccione Aceptar o Aplicar para aceptar los cambios.

Creación y administración del servicio de Windows

Creación de un servicio

Use los comandos de PowerShell para registrar un servicio. Desde un shell de comandos administrativos de PowerShell 6, ejecute los comandos siguientes:

$acl = Get-Acl "{EXE PATH}"
$aclRuleArgs = "{DOMAIN OR COMPUTER NAME\USER}", "Read,Write,ReadAndExecute", "ContainerInherit,ObjectInherit", "None", "Allow"
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($aclRuleArgs)
$acl.SetAccessRule($accessRule)
$acl | Set-Acl "{EXE PATH}"

New-Service -Name {SERVICE NAME} -BinaryPathName "{EXE FILE PATH}" -Credential "{DOMAIN OR COMPUTER NAME\USER}" -Description "{DESCRIPTION}" -DisplayName "{DISPLAY NAME}" -StartupType Automatic
  • {EXE PATH}: ruta de acceso del ejecutable de la aplicación en el host (por ejemplo, d:\myservice). No incluya el archivo ejecutable de la aplicación en la ruta de acceso. No se requiere una barra diagonal al final.
  • {DOMAIN OR COMPUTER NAME\USER}: cuenta de usuario de servicio (por ejemplo, Contoso\ServiceUser).
  • {SERVICE NAME}: nombre de servicio (por ejemplo, MyService).
  • {EXE FILE PATH}: ruta de acceso ejecutable completa de la aplicación (por ejemplo, d:\myservice\myservice.exe). Incluya el nombre de archivo del ejecutable con la extensión.
  • {DESCRIPTION}: descripción del servicio (por ejemplo, My sample service).
  • {DISPLAY NAME}: nombre para mostrar del servicio (por ejemplo, My Service).

iniciar un servicio.

Inicie el servicio con el siguiente comando de PowerShell 6:

Start-Service -Name {SERVICE NAME}

Este comando tarda unos segundos en iniciar el servicio.

Determinación del estado de un servicio

Para comprobar el estado de un servicio, use el siguiente comando de PowerShell 6:

Get-Service -Name {SERVICE NAME}

El estado se notifica como uno de los siguientes valores:

  • Starting
  • Running
  • Stopping
  • Stopped

Detención de un servicio

Detenga un servicio con el siguiente comando de PowerShell 6:

Stop-Service -Name {SERVICE NAME}

Eliminación de un servicio

Tras un breve intervalo para detener un servicio, elimine el servicio con el siguiente comando de PowerShell 6:

Remove-Service -Name {SERVICE NAME}

Escenarios de servidor proxy y equilibrador de carga

Los servicios que interactúan con las solicitudes de Internet o de una red corporativa y están detrás de un proxy o de un equilibrador de carga podrían requerir configuración adicional. Para obtener más información, consulte Configuración de ASP.NET Core para trabajar con servidores proxy y equilibradores de carga.

Configuración de puntos de conexión

ASP.NET Core se enlaza a http://localhost:5000 de forma predeterminada. Configure la dirección URL y el puerto estableciendo la variable de entorno ASPNETCORE_URLS.

Para información sobre otros enfoques de configuración de direcciones URL y puertos, consulte el artículo en cuestión:

En la guía anterior se trata la compatibilidad con los puntos de conexión HTTPS. Por ejemplo, configure la aplicación para HTTPS cuando se use la autenticación con un servicio de Windows.

Nota

No se admite el uso del certificado de desarrollo HTTPS de ASP.NET Core para proteger un punto de conexión de servicio.

Directorio actual y raíz del contenido

El directorio de trabajo actual devuelto por una llamada a GetCurrentDirectory para un servicio de Windows es la carpeta C:\WINDOWS\system32. La carpeta system32 no es una ubicación adecuada para almacenar los archivos de un servicio (por ejemplo los archivos de configuración). Utilice uno de los siguientes enfoques para mantener los archivos de configuración y los activos de un servicio, así como para acceder a ellos.

Uso de ContentRootPath o ContentRootFileProvider

Use IHostEnvironment.ContentRootPath o ContentRootFileProvider para buscar los recursos de una aplicación.

Cuando la aplicación se ejecuta como un servicio, UseWindowsService establece la ruta de acceso ContentRootPath en AppContext.BaseDirectory.

Los archivos de configuración predeterminados de la aplicación, appsettings.jsony appsettings.{Environment}.json, se cargan desde la raíz del contenido de la aplicación mediante una llamada a CreateDefaultBuilder durante la construcción del host.

En el caso de otros archivos de configuración cargados por el código para desarrolladores en ConfigureAppConfiguration, no es necesario llamar a SetBasePath. En el ejemplo siguiente, el archivo custom_settings.json ya se encuentra en la raíz del contenido de la aplicación y se carga sin establecer explícitamente una ruta de acceso base:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .UseWindowsService()
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddJsonFile("custom_settings.json");
            })
            .ConfigureServices((hostContext, services) =>
            {
                services.AddHostedService<Worker>();
            });
}

No intente usar GetCurrentDirectory para obtener una ruta de acceso a recursos porque una aplicación de servicio de Windows devuelve la carpeta C:\WINDOWS\system32 como su directorio actual.

Almacenamiento de los archivos de un servicio en una ubicación adecuada en el disco

Especifique una ruta de acceso absoluta con SetBasePath al utilizar un IConfigurationBuilder a la carpeta que contiene los archivos.

Solucionar problemas

Para solucionar problemas de una aplicación de servicio de Windows, vea Solución de problemas y depuración de proyectos de ASP.NET Core.

Errores comunes

  • Se está usando una versión preliminar o antigua de PowerShell.
  • El servicio registrado no usa la salida publicada de la aplicación del comando dotnet publish. La salida del comando dotnet build no es compatible con la implementación de aplicaciones. Los recursos publicados se encuentran en cualquiera de las siguientes carpetas, según el tipo de implementación:
    • bin/Release/{PLATAFORMA DE DESTINO}/publish (FDD)
    • bin/Release/{PLATAFORMA DE DESTINO}/{IDENTIFICADOR DE RUNTIME}/publish (SCD)
  • El servicio no está en el estado EN EJECUCIÓN.
  • Las rutas de acceso a los recursos que usa la aplicación (por ejemplo, certificados) son incorrectas. La ruta de acceso base de un servicio de Windows es c:\Windows\System32.
  • El usuario no tiene derechos de inicio de sesión como servicio.
  • La contraseña del usuario ha expirado o se ha pasado incorrectamente al ejecutar el comando de PowerShell New-Service.
  • La aplicación requiere autenticación ASP.NET Core, pero no está configurada para conexiones seguras (HTTPS).
  • El puerto de la dirección URL de solicitud es incorrecto o no está configurado correctamente en la aplicación.

Registros de eventos del sistema y de aplicación

Acceda a los registros de eventos del sistema y de aplicación:

  1. Abra el menú Inicio, busque Visor de eventos y seleccione la aplicación Visor de eventos.
  2. En Visor de eventos, abra el nodo Registros de Windows.
  3. Seleccione Sistema para abrir el registro de eventos del sistema. Seleccione Aplicación para abrir el registro de eventos de la aplicación.
  4. Busque los errores asociados a la aplicación objeto del error.

Ejecución de la aplicación en un símbolo del sistema

Muchos errores de inicio no generan información útil en el registro de eventos. La causa de algunos errores se puede encontrar mediante la ejecución de la aplicación en un símbolo del sistema en el sistema de hospedaje. Para registrar detalles adicionales de la aplicación, reduzca el nivel de registro o ejecute la aplicación en el entorno de desarrollo.

Borrado de memorias caché de paquetes

Una aplicación en funcionamiento deja de ejecutarse inmediatamente después de actualizar el SDK de .NET Core en la máquina de desarrollo o de cambiar las versiones del paquete en la aplicación. En algunos casos, los paquetes incoherentes pueden interrumpir una aplicación al realizar actualizaciones importantes. La mayoría de estos problemas puede corregirse siguiendo estas instrucciones:

  1. Elimine las carpetas bin y obj.

  2. Borre las memorias caché del paquete ejecutando dotnet nuget locals all --clear desde un shell de comandos.

    Otra manera de borrar las memorias caché de paquetes es usando la herramienta nuget.exe y ejecutando el comando nuget locals all -clear. nuget.exe no es una instalación agrupada con el sistema operativo de escritorio de Windows y se debe obtener de forma independiente en el sitio web de NuGet.

  3. Restaure el proyecto y vuelva a compilarlo.

  4. Elimine todos los archivos de la carpeta de implementación del servidor antes de volver a implementar la aplicación.

Aplicación lenta o sin respuesta

Un volcado de memoria es una instantánea de la memoria del sistema que puede ayudar a determinar la causa de un bloqueo de la aplicación, un error de inicio o una aplicación lenta.

Bloqueo o excepción de la aplicación

Obtenga y analice un volcado de memoria en Informe de errores de Windows (WER):

  1. Cree una carpeta para almacenar los archivos de volcado de memoria en c:\dumps.

  2. Ejecute el script EnableDumps PowerShell con el nombre del archivo ejecutable de la aplicación:

    .\EnableDumps {APPLICATION EXE} c:\dumps
    
  3. Ejecute la aplicación en las condiciones que hacen que se produzca el bloqueo.

  4. Una vez que se haya producido el bloqueo, ejecute el script DisableDumps de PowerShell:

    .\DisableDumps {APPLICATION EXE}
    

Después de que se bloquee la aplicación y se complete la recopilación del volcado de memoria, la aplicación puede finalizar con normalidad. El script de PowerShell configura WER de modo que recopile un máximo de cinco volcados de memoria por aplicación.

Advertencia

Los volcados de memoria pueden ocupar una gran cantidad de espacio en disco (hasta varios gigabytes cada uno).

La aplicación deja de responder, produce un error durante el inicio o se ejecuta con normalidad

Si una aplicación deja de responder pero no se bloquea, produce un error durante el inicio o se ejecuta con normalidad, consulta User-Mode Dump Files: Choosing the Best Tool para seleccionar una herramienta apropiada para generar el volcado de memoria:

Análisis del volcado de memoria

El volcado de memoria se puede analizar de varias maneras. Para obtener más información, vea Analyzing a User-Mode Dump File (Análisis de un archivo de volcado de memoria en modo de usuario).

Recursos adicionales

Una aplicación de ASP.NET Core se puede hospedar en Windows sin usar IIS como servicio de Windows. Cuando se hospeda como un servicio de Windows, la aplicación se inicia automáticamente después de reiniciar el servidor.

Vea o descargue el código de ejemplo (cómo descargarlo)

Requisitos previos

Plantilla Worker Service

La plantilla Worker Service de ASP.NET Core sirve de punto de partida para escribir aplicaciones de servicio de larga duración. Para usar la plantilla como base de una aplicación de servicio de Windows:

  1. Cree una aplicación Worker Service con la plantilla de .NET Core.
  2. Siga las instrucciones de la sección Configuración de aplicaciones para actualizar la aplicación Worker Service a fin de que se ejecute como un servicio de Windows.
  1. Cree un nuevo proyecto.
  2. Seleccione Worker Service (Servicio de Worker). Seleccione Siguiente.
  3. Proporcione un nombre para el proyecto en el campo Nombre del proyecto o acepte el predeterminado. Seleccione Crear.
  4. En el cuadro de diálogo Crear un servicio de Worker, seleccione Crear.

Configuración de aplicaciones

La aplicación requiere una referencia de paquete para Microsoft.Extensions.Hosting.WindowsServices.

Se llama a IHostBuilder.UseWindowsService al compilar el host. Si la aplicación se ejecuta como un servicio de Windows, el método:

  • Establece la vigencia del host en WindowsServiceLifetime.
  • Establece la raíz del contenido en AppContext.BaseDirectory. Para obtener más información, consulte la sección Directorio actual y raíz del contenido.
  • Habilita el registro en el registro de eventos:
    • El nombre de la aplicación se usa como nombre de origen predeterminado.
    • El nivel de registro predeterminado es Advertencia o superior para una aplicación basada en una plantilla de ASP.NET Core que llama a CreateDefaultBuilder con el fin de compilar el host.
    • Invalide el nivel de registro predeterminado con la clave Logging:EventLog:LogLevel:Default en appsettings.json/appsettings.{Environment}.json u otro proveedor de configuración.
    • Los administradores son los únicos que pueden crear nuevos orígenes de eventos. Cuando no se puede crear un origen de eventos con el nombre de la aplicación, se registra una advertencia para el origen Aplicación y los registros de eventos se deshabilitan.

En CreateHostBuilder de Program.cs:

Host.CreateDefaultBuilder(args)
    .UseWindowsService()
    ...

Las aplicaciones de ejemplo siguientes acompañan a este tema:

  • Ejemplo de Background Worker Service: un ejemplo de una aplicación que no es para la Web basado en la plantilla Worker Service que usa servicios hospedados para las tareas en segundo plano.
  • Ejemplo de App Service web: un ejemplo de aplicación web de Razor Pages que se ejecuta como un servicio de Windows con servicios hospedados para las tareas en segundo plano.

Para obtener instrucciones de MVC, vea los artículos Información general de ASP.NET Core MVC y Migración de ASP.NET Core 2.2 a 3.0.

Tipo de implementación

Para obtener información y consejos sobre los escenarios de implementación, consulte Implementación de aplicaciones .NET Core.

SDK

En el caso de un servicio basado en una aplicación web que use los marcos Razor Pages o MVC, especifique el SDK web en el archivo de proyecto:

<Project Sdk="Microsoft.NET.Sdk.Web">

Si el servicio solo ejecuta tareas en segundo plano (por ejemplo, servicios hospedados), especifique el SDK de Worker en el archivo de proyecto:

<Project Sdk="Microsoft.NET.Sdk.Worker">

Implementación dependiente de marco (FDD)

La implementación dependiente de marco de trabajo (FDD) se basa en la presencia de una versión compartida de .NET Core en todo el sistema en el sistema de destino. Cuando se adopta el escenario FDD siguiendo las instrucciones de este artículo, el SDK genera un archivo ejecutable ( .exe), denominado ejecutable dependiente del marco.

Si se usa el SDK web, para una aplicación de Windows Services no se requiere un archivo web.config, que normalmente se crea cuando se publica una aplicación ASP.NET Core. Para deshabilitar la creación de un archivo web.config agregue la propiedad <IsTransformWebConfigDisabled> establecida en true.

<PropertyGroup>
  <TargetFramework>netcoreapp3.0</TargetFramework>
  <IsTransformWebConfigDisabled>true</IsTransformWebConfigDisabled>
</PropertyGroup>

Implementación autocontenida (SCD)

Una implementación autocontenida (SCD) no depende de la presencia de un marco compartido en el sistema host. El tiempo de ejecución y las dependencias de la aplicación se implementan con la aplicación.

Un identificador en tiempo de ejecución (RID) se incluye en el <PropertyGroup> que contiene la plataforma de destino:

<RuntimeIdentifier>win7-x64</RuntimeIdentifier>

Para publicar para varios RID:

  • Proporcione los RID en una lista delimitada por punto y coma.
  • Utilice el nombre de propiedad <RuntimeIdentifiers> (en plural).

Para más información, vea el Catálogo de identificadores de entorno de ejecución (RID) de .NET Core.

Cuenta de usuario de servicio

Para crear una cuenta de usuario para un servicio, use el cmdlet New-LocalUser de un shell de comandos administrativos de PowerShell 6.

En la actualización de octubre de 2018 de Windows 10 (versión 1809/compilación 10.0.17763) o posterior:

New-LocalUser -Name {SERVICE NAME}

En el sistema operativo Windows anterior a la actualización de octubre de 2018 de Windows 10 (versión 1809/compilación 10.0.17763):

powershell -Command "New-LocalUser -Name {SERVICE NAME}"

Proporcione una contraseña segura cuando se le solicite.

A menos que el parámetro -AccountExpires se proporcione para el cmdlet New-LocalUser con una fecha de expiración DateTime, la cuenta no expirará.

Para más información, vea Microsoft.PowerShell.LocalAccounts y Service User Accounts (Cuentas de usuario del servicio).

Un enfoque alternativo de administración de usuarios al usar Active Directory consiste en usar cuentas de servicio administradas. Para obtener más información, consulte grupo Managed Service Accounts Overview (Información general sobre cuentas de servicio administradas de grupo).

Derechos para iniciar sesión como servicio

Para establecer los derechos de Iniciar sesión como servicio para una cuenta de usuario del servicio:

  1. Abra el editor de la Directiva de seguridad local mediante la ejecución de secpol.msc.
  2. Expanda el nodo Directivas locales y, después, seleccione Asignación de derechos de usuario.
  3. Abra la directiva Iniciar sesión como servicio.
  4. Seleccione Agregar usuario o grupo.
  5. Proporcione el nombre de objeto (cuenta de usuario) mediante cualquiera de los métodos siguientes:
    1. Escriba la cuenta de usuario ({DOMAIN OR COMPUTER NAME\USER}) en el campo del nombre de objeto y seleccione Aceptar para agregar el usuario a la directiva.
    2. Seleccione Opciones avanzadas. Seleccione Buscar ahora. Seleccione la cuenta de usuario de la lista. Seleccione Aceptar. Seleccione Aceptar nuevo para agregar el usuario a la directiva.
  6. Seleccione Aceptar o Aplicar para aceptar los cambios.

Creación y administración del servicio de Windows

Creación de un servicio

Use los comandos de PowerShell para registrar un servicio. Desde un shell de comandos administrativos de PowerShell 6, ejecute los comandos siguientes:

$acl = Get-Acl "{EXE PATH}"
$aclRuleArgs = "{DOMAIN OR COMPUTER NAME\USER}", "Read,Write,ReadAndExecute", "ContainerInherit,ObjectInherit", "None", "Allow"
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($aclRuleArgs)
$acl.SetAccessRule($accessRule)
$acl | Set-Acl "{EXE PATH}"

New-Service -Name {SERVICE NAME} -BinaryPathName "{EXE FILE PATH}" -Credential "{DOMAIN OR COMPUTER NAME\USER}" -Description "{DESCRIPTION}" -DisplayName "{DISPLAY NAME}" -StartupType Automatic
  • {EXE PATH}: ruta de acceso del ejecutable de la aplicación en el host (por ejemplo, d:\myservice). No incluya el archivo ejecutable de la aplicación en la ruta de acceso. No se requiere una barra diagonal al final.
  • {DOMAIN OR COMPUTER NAME\USER}: cuenta de usuario de servicio (por ejemplo, Contoso\ServiceUser).
  • {SERVICE NAME}: nombre de servicio (por ejemplo, MyService).
  • {EXE FILE PATH}: ruta de acceso ejecutable completa de la aplicación (por ejemplo, d:\myservice\myservice.exe). Incluya el nombre de archivo del ejecutable con la extensión.
  • {DESCRIPTION}: descripción del servicio (por ejemplo, My sample service).
  • {DISPLAY NAME}: nombre para mostrar del servicio (por ejemplo, My Service).

iniciar un servicio.

Inicie el servicio con el siguiente comando de PowerShell 6:

Start-Service -Name {SERVICE NAME}

Este comando tarda unos segundos en iniciar el servicio.

Determinación del estado de un servicio

Para comprobar el estado de un servicio, use el siguiente comando de PowerShell 6:

Get-Service -Name {SERVICE NAME}

El estado se notifica como uno de los siguientes valores:

  • Starting
  • Running
  • Stopping
  • Stopped

Detención de un servicio

Detenga un servicio con el siguiente comando de PowerShell 6:

Stop-Service -Name {SERVICE NAME}

Eliminación de un servicio

Tras un breve intervalo para detener un servicio, elimine el servicio con el siguiente comando de PowerShell 6:

Remove-Service -Name {SERVICE NAME}

Escenarios de servidor proxy y equilibrador de carga

Los servicios que interactúan con las solicitudes de Internet o de una red corporativa y están detrás de un proxy o de un equilibrador de carga podrían requerir configuración adicional. Para obtener más información, consulte Configuración de ASP.NET Core para trabajar con servidores proxy y equilibradores de carga.

Configuración de puntos de conexión

ASP.NET Core se enlaza a http://localhost:5000 de forma predeterminada. Configure la dirección URL y el puerto estableciendo la variable de entorno ASPNETCORE_URLS.

Para información sobre otros enfoques de configuración de direcciones URL y puertos, consulte el artículo en cuestión:

En la guía anterior se trata la compatibilidad con los puntos de conexión HTTPS. Por ejemplo, configure la aplicación para HTTPS cuando se use la autenticación con un servicio de Windows.

Nota

No se admite el uso del certificado de desarrollo HTTPS de ASP.NET Core para proteger un punto de conexión de servicio.

Directorio actual y raíz del contenido

El directorio de trabajo actual devuelto por una llamada a GetCurrentDirectory para un servicio de Windows es la carpeta C:\WINDOWS\system32. La carpeta system32 no es una ubicación adecuada para almacenar los archivos de un servicio (por ejemplo los archivos de configuración). Utilice uno de los siguientes enfoques para mantener los archivos de configuración y los activos de un servicio, así como para acceder a ellos.

Uso de ContentRootPath o ContentRootFileProvider

Use IHostEnvironment.ContentRootPath o ContentRootFileProvider para buscar los recursos de una aplicación.

Cuando la aplicación se ejecuta como un servicio, UseWindowsService establece la ruta de acceso ContentRootPath en AppContext.BaseDirectory.

Los archivos de configuración predeterminados de la aplicación, appsettings.jsony appsettings.{Environment}.json, se cargan desde la raíz del contenido de la aplicación mediante una llamada a CreateDefaultBuilder durante la construcción del host.

En el caso de otros archivos de configuración cargados por el código para desarrolladores en ConfigureAppConfiguration, no es necesario llamar a SetBasePath. En el ejemplo siguiente, el archivo custom_settings.json ya se encuentra en la raíz del contenido de la aplicación y se carga sin establecer explícitamente una ruta de acceso base:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .UseWindowsService()
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddJsonFile("custom_settings.json");
            })
            .ConfigureServices((hostContext, services) =>
            {
                services.AddHostedService<Worker>();
            });
}

No intente usar GetCurrentDirectory para obtener una ruta de acceso a recursos porque una aplicación de servicio de Windows devuelve la carpeta C:\WINDOWS\system32 como su directorio actual.

Almacenamiento de los archivos de un servicio en una ubicación adecuada en el disco

Especifique una ruta de acceso absoluta con SetBasePath al utilizar un IConfigurationBuilder a la carpeta que contiene los archivos.

Solucionar problemas

Para solucionar problemas de una aplicación de servicio de Windows, vea Solución de problemas y depuración de proyectos de ASP.NET Core.

Errores comunes

  • Se está usando una versión preliminar o antigua de PowerShell.
  • El servicio registrado no usa la salida publicada de la aplicación del comando dotnet publish. La salida del comando dotnet build no es compatible con la implementación de aplicaciones. Los recursos publicados se encuentran en cualquiera de las siguientes carpetas, según el tipo de implementación:
    • bin/Release/{PLATAFORMA DE DESTINO}/publish (FDD)
    • bin/Release/{PLATAFORMA DE DESTINO}/{IDENTIFICADOR DE RUNTIME}/publish (SCD)
  • El servicio no está en el estado EN EJECUCIÓN.
  • Las rutas de acceso a los recursos que usa la aplicación (por ejemplo, certificados) son incorrectas. La ruta de acceso base de un servicio de Windows es c:\Windows\System32.
  • El usuario no tiene derechos de inicio de sesión como servicio.
  • La contraseña del usuario ha expirado o se ha pasado incorrectamente al ejecutar el comando de PowerShell New-Service.
  • La aplicación requiere autenticación ASP.NET Core, pero no está configurada para conexiones seguras (HTTPS).
  • El puerto de la dirección URL de solicitud es incorrecto o no está configurado correctamente en la aplicación.

Registros de eventos del sistema y de aplicación

Acceda a los registros de eventos del sistema y de aplicación:

  1. Abra el menú Inicio, busque Visor de eventos y seleccione la aplicación Visor de eventos.
  2. En Visor de eventos, abra el nodo Registros de Windows.
  3. Seleccione Sistema para abrir el registro de eventos del sistema. Seleccione Aplicación para abrir el registro de eventos de la aplicación.
  4. Busque los errores asociados a la aplicación objeto del error.

Ejecución de la aplicación en un símbolo del sistema

Muchos errores de inicio no generan información útil en el registro de eventos. La causa de algunos errores se puede encontrar mediante la ejecución de la aplicación en un símbolo del sistema en el sistema de hospedaje. Para registrar detalles adicionales de la aplicación, reduzca el nivel de registro o ejecute la aplicación en el entorno de desarrollo.

Borrado de memorias caché de paquetes

Una aplicación en funcionamiento deja de ejecutarse inmediatamente después de actualizar el SDK de .NET Core en la máquina de desarrollo o de cambiar las versiones del paquete en la aplicación. En algunos casos, los paquetes incoherentes pueden interrumpir una aplicación al realizar actualizaciones importantes. La mayoría de estos problemas puede corregirse siguiendo estas instrucciones:

  1. Elimine las carpetas bin y obj.

  2. Borre las memorias caché del paquete ejecutando dotnet nuget locals all --clear desde un shell de comandos.

    Otra manera de borrar las memorias caché de paquetes es usando la herramienta nuget.exe y ejecutando el comando nuget locals all -clear. nuget.exe no es una instalación agrupada con el sistema operativo de escritorio de Windows y se debe obtener de forma independiente en el sitio web de NuGet.

  3. Restaure el proyecto y vuelva a compilarlo.

  4. Elimine todos los archivos de la carpeta de implementación del servidor antes de volver a implementar la aplicación.

Aplicación lenta o sin respuesta

Un volcado de memoria es una instantánea de la memoria del sistema que puede ayudar a determinar la causa de un bloqueo de la aplicación, un error de inicio o una aplicación lenta.

Bloqueo o excepción de la aplicación

Obtenga y analice un volcado de memoria en Informe de errores de Windows (WER):

  1. Cree una carpeta para almacenar los archivos de volcado de memoria en c:\dumps.

  2. Ejecute el script EnableDumps PowerShell con el nombre del archivo ejecutable de la aplicación:

    .\EnableDumps {APPLICATION EXE} c:\dumps
    
  3. Ejecute la aplicación en las condiciones que hacen que se produzca el bloqueo.

  4. Una vez que se haya producido el bloqueo, ejecute el script DisableDumps de PowerShell:

    .\DisableDumps {APPLICATION EXE}
    

Después de que se bloquee la aplicación y se complete la recopilación del volcado de memoria, la aplicación puede finalizar con normalidad. El script de PowerShell configura WER de modo que recopile un máximo de cinco volcados de memoria por aplicación.

Advertencia

Los volcados de memoria pueden ocupar una gran cantidad de espacio en disco (hasta varios gigabytes cada uno).

La aplicación deja de responder, produce un error durante el inicio o se ejecuta con normalidad

Si una aplicación deja de responder pero no se bloquea, produce un error durante el inicio o se ejecuta con normalidad, consulta User-Mode Dump Files: Choosing the Best Tool para seleccionar una herramienta apropiada para generar el volcado de memoria:

Análisis del volcado de memoria

El volcado de memoria se puede analizar de varias maneras. Para obtener más información, vea Analyzing a User-Mode Dump File (Análisis de un archivo de volcado de memoria en modo de usuario).

Recursos adicionales