.net core console app as windows service- Is it possible to safely kill execution of started process without using Kill() method?

痴心易碎 提交于 2019-12-24 03:07:46

问题


I have a dotnet core 2.2 console app.
I hosted it as windows service.(Service name: "MyService1")
"MyService1" starts up another dotnet core WebAPI.
The problem is, how do I safely kill the WebAPI process when the "MyService1" is stopped?

Here is how I tried to do that but I can still see the process in the task manager.

public class MyService : IHostedService, IDisposable
{
    private Timer _timer;
    static Process webAPI;

    public Task StartAsync(CancellationToken cancellationToken)
    {
        _timer = new Timer(
            (e) => StartChildProcess(),
            null,
            TimeSpan.Zero,
            TimeSpan.FromMinutes(1));

        return Task.CompletedTask;
    }

    public void StartChildProcess()
    {
        try
        {
            webAPI = new Process();
            webAPI.StartInfo.UseShellExecute = false;
            webAPI.StartInfo.FileName = @"C:\Project\bin\Debug\netcoreapp2.2\publish\WebAPI.exe";
            webAPI.Start();
        }
        catch (Exception e)
        {
            // Handle exception
        }
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        // TODO: Add code to stop child process safely
        webAPI.Close();  

        _timer?.Change(Timeout.Infinite, 0);

        return Task.CompletedTask;
    }

    public void Dispose()
    {
        _timer?.Dispose();
    }
}

Is it possible to do that without using Kill() method?


回答1:


I'm not sure where you're starting your other WebAPI process from, nut you have 2 options:

  1. Register to the ProcessExit event from your Program.cs file and close the WebAPI process there, like this:

    class Program
    {
        static Process webAPI;
    
        static async Task Main(string[] args)
        {
            AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
    
            webAPI = new Process
            {
                StartInfo = new ProcessStartInfo("dotnet")
                {
                    UseShellExecute = false,
                    CreateNoWindow = true,
    
                    //If you want to run as .exe
                    FileName = @"C:\Project\bin\Debug\netcoreapp2.2\publish\WebAPI.exe",
    
                    //If you want to run the .dll
                    WorkingDirectory = "C:/Project/publish",
                    Arguments = "WebAPI.dll"
                }
            };
            using (webAPI)
            {
                webAPI.Start();
                webAPI.WaitForExit();
            }
        }
    
        static void CurrentDomain_ProcessExit(object sender, EventArgs e)
        {
            webAPI.Close();
        }
    }
    
  2. Pass the service process id to the WebAPI process and monitor it from there, like this:

    class Program
    {
        static async Task Main(string[] args)
        {
            try { }
            catch { }
            // Make sure you use a finally block.
            // If for any reason your code crashes you'd still want this part to run.
            finally
            {
                if (int.TryPasre(args[X], out parentProcessId))
                    MonitorAgentProcess(parentProcessId);
            }
        }
    
        static void MonitorAgentProcess(int parentProcessId)
        {
            try
            {
                Process process = Process.GetProcessById(parentProcessId);
                Task.Run(() => process.WaitForExit())
                    .ContinueWith(t => Environment.Exit(-1));
            }
            catch {}
        }
    }
    



回答2:


The problem you have there is that your webAPI task is actually a separate EXE, not integrated into the service. Unless the service has a way of interacting with it and requesting a graceful shut-down then you will have to terminate the EXE process in a manor that is decidedly not clean.



来源:https://stackoverflow.com/questions/56127334/net-core-console-app-as-windows-service-is-it-possible-to-safely-kill-executio

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!