所以。我创建了一个辅助服务并希望将其作为 Windows 服务运行。它在本地工作。我通过 powershell new-service 命令将其安装到 Windows 服务器。当我通过服务启动它时,它尝试启动,等待 30 秒(加载栏正在进行)并失败。在事件查看器中,我看到一般错误:
现在,奇怪的是,我向服务逻辑添加了一些日志记录,它实际上做了需要的事情,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");
}
}
}
由于我不知道您用来创建 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
文件来注册服务。
我们刚刚解决了同样的问题!
问题是服务控制管理器需要额外的回调才能将服务切换到“运行”。
这由 Microsoft.Extensions.Hosting.WindowsServices(单独的 NuGet)处理,并附加 CreateHostBuilder(...).UseWindowsService();