Search code examples
c#windows.net-corewindows-servicesbackgroundworker

Is there a way to disable the stop button in Windows Worker Services (Background Services) in .Net Core?


I’m creating a windows worker service in Visual Studio 2022 with new guidelines from Microsoft to create windows services using .Net Core 5.0 Windows Service using BackgroundService.

I found out that there was no property in the Background class to disable stop button - (CanStop property is missing) after the service is installed, like we do in Native Windows Services built using .Net Framework.

Is there a workaround for this problem or will they add new features in the upcoming release for Background services?


Solution

  • Well if you call UseWindowsService this happens:

    public static IHostBuilder UseWindowsService(this IHostBuilder hostBuilder)
    {
        return UseWindowsService(hostBuilder, _ => { });
    }
    
    ...
    
    public static IHostBuilder UseWindowsService(this IHostBuilder hostBuilder, Action<WindowsServiceLifetimeOptions> configure)
    {
        if (WindowsServiceHelpers.IsWindowsService())
        {
            // Host.CreateDefaultBuilder uses CurrentDirectory for VS scenarios, but CurrentDirectory for services is c:\Windows\System32.
            hostBuilder.UseContentRoot(AppContext.BaseDirectory);
            hostBuilder.ConfigureLogging((hostingContext, logging) =>
            {
                logging.AddEventLog();
            })
            .ConfigureServices((hostContext, services) =>
            {
                services.AddSingleton<IHostLifetime, WindowsServiceLifetime>();
                services.Configure<EventLogSettings>(settings =>
                {
                    if (string.IsNullOrEmpty(settings.SourceName))
                    {
                        settings.SourceName = hostContext.HostingEnvironment.ApplicationName;
                    }
                });
                services.Configure(configure);
            });
        }
    
        return hostBuilder;
    }
    
    

    WindowsServiceLifetime implements ServiceBase which has the property:

    https://learn.microsoft.com/en-us/dotnet/api/system.serviceprocess.servicebase.canstop?view=dotnet-plat-ext-6.0

    So perhaps you could do something like this:

    var host = Host.CreateDefaultBuilder()
        .UseWindowsService()
        .Build();
    
    var windowsServiceLifetime = host.Services.GetService<IHostLifetime>() as WindowsServiceLifetime;
    
    // NOTE .Services.GetService<IHostLifetime>() will return IConsoleLifetime when running under console!
    if (windowsServiceLifetime != null)
    {
        windowsServiceLifetime.CanStop = false;
    }
    

    I'm unsure about this but i did a little investigation and hence this post. I'll remove it if this is not valuable.