Я хочу перезапустить Kestrel (asp. net core 3.1) через авторизованный HTTP-запрос. Kestrel содержится в службе Windows, настроенной на автоматический перезапуск в случае сбоя. Насколько я знаю, самый простой способ - вернуть код выхода, отличный от 0, windows сделает все остальное.
В свете этого код, который я написал, на самом деле прост:
public MaintenanceController(IHostApplicationLifetime hostLifetime)
{
this.HostLifetime = hostLifetime ?? throw new ArgumentNullException(nameof(hostLifetime));
}
[HttpPost]
[Route("service/restart")]
[Authorize("AdminOnly")]
public ActionResult RestartService()
{
Program.IsRestart = true; //see below
this.HostLifetime.StopApplication();
//this does not work!
if (HostLifetime is WindowsServiceLifetime lifetime)
{
lifetime.ExitCode = 1;
}
//neither this!
Environment.ExitCode = 1;
return Ok();
}
Единственный способ заставить windows перезапустить службу - это просто вызвать
Environment.Exit(1);
без HostLifetime.StopApplication ();
Но проблема с Environment.Exit вызвана только это вызывает не изящное завершение работы, чего я хочу полностью избежать. в Startup.cs:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime applicationLifetime)
{
[...]
applicationLifetime.ApplicationStopped.Register(() =>
{
//this can be set in the controller
if (Program.IsRestart)
{
Environment.Exit(1);
}
});
}
, но при вызове после ApplicationStopped Environment.Exit (1), по-видимому, ничего не делает, на самом деле даже внутри средства просмотра событий нет следов завершения работы служб с ошибкой, поэтому windows ничего не делает.
UPDATE
Возвращаясь к classi c, я изменил основную точку входа, чтобы вернуть int и вернуть 1. Тем не менее windows не перезапускает службу ни неудачный вход y записывается в программу просмотра событий. Похоже, всегда останавливается изящно