Home > OS >  Dotnet 5.0 Service Runs as EXE but when starting service times out with 1053: Service did not respon
Dotnet 5.0 Service Runs as EXE but when starting service times out with 1053: Service did not respon

Time:10-14

I have a background with Linux for running services, first time working on Microsoft environment. Code could be improved in many areas I'm sure, first step is getting a running service. I've referenced many posts and documentation, but I'm not yet able to fully understand how Microsoft services and dotnet interact as compared to a linux environment with apache running a django application for example.

I'm using Visual Basic for Mac as development, dotnet 5.0 C# environment to build a service that listens to a directory for new file creation and then runs a script with the file information. I deploy to a Windows 10 x-64 with dotnet 5.0 environment. I can compile an .exe and run on the target machine and it works fine. I then build the service with sc.exe, and whether I run from the Services Manager GUI or from Powershell, the service will always time out. I am trying to figure out how to get the service to continue running. The Service will write to my log files, and it will even process the file if a new file as added to the target directory, but then it will always proceed to time out with the following error:

Error 1053: the service did not respond to the start or control request in a timely fashion

My steps and code below:

Create Worker Service with Visual Studio for Mac.

My Program.cs was built from a template and added a few other methods that are empty now, but I thought would be useful.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

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

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    //config.AddJsonFile("custom_settings.json");
                })
                .ConfigureLogging(logging =>
                {
                    //builder.AddFile("logs/app-{Date}.json"), isJson: true);
                })
                .ConfigureServices((hostContext, services) =>
                {
                    services.AddHostedService<Worker>();
                });
    }
}

Next is Worker.cs:

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using HttpClientSample;

namespace MyService
{

    public class Worker : BackgroundService
    {

        private readonly ILogger<Worker> _logger;

        public Worker(ILogger<Worker> logger)
        {
            _logger = logger;
        }

        public override async Task StartAsync(CancellationToken cancellationToken)
        {
            string path = @"C:\log.txt";
            string startText = "Start"   Environment.NewLine;
            File.AppendAllText(path, startText);
            await ExecuteAsync(cancellationToken);
        }

        public override async Task StopAsync(CancellationToken cancellationToken)
        {
            string path = @"C:\log.txt";
            string stopText = "Stop"   Environment.NewLine;
            File.AppendAllText(path, stopText);
            await base.StopAsync(cancellationToken);
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {

            string path = @"C:\log.txt";
            string writeText = "Execute Async"   Environment.NewLine;
            File.AppendAllText(path, writeText);
            FileSystemWatcher watcher = new FileSystemWatcher();
            watcher.Path = @"C:\files\";
            watcher.NotifyFilter = NotifyFilters.FileName;
            watcher.Created  = OnCreated;
            watcher.Filter = "*.*";
            watcher.EnableRaisingEvents = true;
            File.AppendAllText(path, "watcher engaged.");

            while (!stoppingToken.IsCancellationRequested)
            {
                _logger.LogInformation("worker running at: {time}", DateTimeOffset.Now);
                try
                {
                    await Task.Delay(1000, stoppingToken);
                }
                catch (OperationCanceledException)
                {
                    break;
                }
            }
            
        }

        private static void OnCreated(object sender, FileSystemEventArgs e)
        {
            string path = @"C:\log.txt";
            string writeText = $"e: {e}";
            File.AppendAllText(path, writeText);
            MyProgram myProgram = new MyProgram(e.FullPath);
        }
    }
}

I then process in MyProgram and everything works fine.

For the service, I first compile to correct runtime with the following command: dotnet publish -c Release -r win10-x64. Then I FTP the publish folder over to the Windows 10 machine, run the .exe as the admin profile and it works fine, then create a service from the file via the following: sc.exe create myService binPath= "C:\path\to\executable.exe". I then proceed to run this service from the Services Manager or from Powershell with sc.exe start myService. After approximately 60 seconds I receive the 1053 error.

I don't understand what's required to keep the service running. Steps I've tried below:

  1. I've ensured I'm pointing to the exe when building the service.
  2. I've already increased the timeout via registry as suggested in several sites: here.
  3. I've checked in the Event Viewer for dotnet or services manager issues and wasn't able to find the cause of the issue.
  4. I've tried the local system account as well as admin account to run the service and it still times out.
  5. I've seen InstallUtil as a suggested alternative to sc.exe, but I haven't tried it. I'm not sure how much a difference the tool makes?
  6. Would using the WindowsService vs BackgroundService make the difference when trying to run this via Services Manager?
  7. Is there some signal or return value that the Program needs to implement in order to let the Service know to continue running? There's already a Task.delay() implemented and return values for the StartTask and ExecuteTask methods.

Any suggestions on troubleshooting, solving the problem, or improving my post would all be appreciated. Thank you!

CodePudding user response:

A service process must call the right dll function to indicate that it is starting, and to receive pause / stop events.

In .net there's an implementation of these dll calls built into System.ServiceProcess.ServiceBase

There's an implementation of a service built into asp.net, which I believe pre-dates the introduction of the generic host. Just calling IWebHost.RunAsService() would be enough to glue the windows service start / stop events into the web host start / stop lifetime.

I believe all you need to do is call .UseWindowsService() when configuring your host builder. And this should work for either a console program, or a web host.

  • Related