无法将worker服务作为Windows服务启动

问题描述 投票:0回答:2

所以。我创建了一个辅助服务并希望将其作为 Windows 服务运行。它在本地工作。我通过 powershell new-service 命令将其安装到 Windows 服务器。当我通过服务启动它时,它尝试启动,等待 30 秒(加载栏正在进行)并失败。在事件查看器中,我看到一般错误:

  1. 等待 MyService 服务连接时超时(30000 毫秒)。
  2. MyService 服务由于以下错误而无法启动: 服务没有及时响应启动或控制请求。

现在,奇怪的是,我向服务逻辑添加了一些日志记录,它实际上做了需要的事情,Windows 只是无法启动它,即服务没有响应启动,但可以工作(在服务器杀死它之后持续 30 秒)因为它没有给出启动响应)。 我如何解决它? 我的程序.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");

            });
}

工人服务:

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");
        }
    }
}
c# asp.net-core windows-services backgroundworker windows-server
2个回答
0
投票

由于我不知道您用来创建 Windows 服务的 powershell new-service 命令,因此为了这个答案,我将假设该问题与我遇到的问题有关。

在我的例子中,我使用 Windows 命令提示符创建并启动名为

Worker.Service
的服务。

这就是我遇到

The service did not respond to the start or control request in a timely fashion.
错误的方式:

sc create Worker.Service binPath="C:\Users\<user.name>\source\repos\<repo>\Worker.Service\bin\Debug\netcoreapp3.1\Worker.Service.dll"

sc start Worker.Service

以下是正确的启动方法:

sc create Worker.Service binPath="C:\Users\<user.name>\source\repos\<repo>\Worker.Service\bin\Debug\netcoreapp3.1\Worker.Service.exe"

sc start Worker.Service

binPath
可以通过 Visual Studio 的构建输出窗口获得。但请确保您使用
.exe
文件而不是
.dll
文件来注册服务。


0
投票

我们刚刚解决了同样的问题!

问题是服务控制管理器需要额外的回调才能将服务切换到“运行”。

这由 Microsoft.Extensions.Hosting.WindowsServices(单独的 NuGet)处理,并附加 CreateHostBuilder(...).UseWindowsService();

© www.soinside.com 2019 - 2024. All rights reserved.