So. I created a worker service and want to run it as windows service. It works locally. I installed it to windows server via powershell new-service command. When I start it via Services, it attempts to start, waits for 30 seconds (with loading bar progressing) and fails. In event viewer I see generic errors:
Now, the weird thing is, I added some logging to service logic, and it actually does needed stuff, windows just fails to start it, i.e. service does not respond to start, but works (for 30 seconds, after that server kills it because it gave no response for start). How do I fix it? My Program.cs:
public class Program
{
public static void Main(string[] args)
{
try
{
Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
CreateHostBuilder(args).Build().Run();
}
catch (Exception ex)
{
File.AppendAllText("templogs.txt", ex.Message + "\r\n");
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseWindowsService()
.ConfigureServices((hostContext, services) =>
{
IConfiguration configuration = hostContext.Configuration;
services.AddHostedService<Worker>();
services.AddScoped<IActionHandler, ActionHandler>();
services.AddScoped<IHttpHandler, HttpHandler>();
services.AddDbContext<DbContext>(options =>
{
options.UseSqlServer(configuration.GetConnectionString("DefaultConnection"));
});
File.AppendAllText("templogs.txt", "context registered\r\n");
});
}
Worker service:
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
private readonly List<string> _inactiveStatuses;
private readonly IServiceProvider _services;
private readonly string _connectionString;
public Worker(ILogger<Worker> logger, IConfiguration config, IServiceProvider services)
{
try
{
_logger = logger;
_inactiveStatuses = config.GetSection("InactiveStatuses").GetChildren().Select(a => a.Value).ToList();
_services = services;
_connectionString = config.GetConnectionString("DefaultConnection");
}
catch (Exception ex)
{
File.AppendAllText("templogs.txt", ex.Message + "\r\n");
}
}
public override async Task StartAsync(CancellationToken cancellationToken)
{
await base.StartAsync(cancellationToken);
}
public override async Task StopAsync(CancellationToken cancellationToken)
{
await base.StopAsync(cancellationToken);
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
try
{
using (var scope = _services.CreateScope())
{
File.AppendAllText("templogs.txt", "scope created\r\n");
var actionHandler =
scope.ServiceProvider
.GetRequiredService<IActionHandler>();
var dbContext = scope.ServiceProvider.GetRequiredService<DbContext>();
var activeStatuses = dbContext.Statuses.Where(a => !_inactiveStatuses.Contains(a.Name)).ToDictionary(a => a.Id, a => a.Name);
List<Guid> activeStatusGuids = activeStatuses.Keys.ToList();
while (!stoppingToken.IsCancellationRequested)
{
File.AppendAllText("templogs.txt", "while strated\r\n");
//some logic
File.AppendAllText("templogs.txt", "first cycle\r\n");
await Task.Delay(1000, stoppingToken);
}
}
}
catch (Exception ex)
{
File.AppendAllText("templogs.txt", ex.Message + "\r\n");
}
}
}
We just fought the same issue!
The problem is that Service Control Manager requires an extra callback to switch the service to "running".
This is handled by the Microsoft.Extensions.Hosting.WindowsServices (separate NuGet), and appending CreateHostBuilder(...).UseWindowsService();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With