【问题标题】:.net core - How to properly kill started process?.net core - 如何正确杀死启动的进程?
【发布时间】:2018-06-17 12:25:32
【问题描述】:

我有一个启动另一个 dotnet core WebAPI 的 dotnet core 2.0 控制台应用程序。 问题是,当控制台应用程序关闭时,我如何干净地杀死 WebAPI 进程?因为到目前为止,我无法启动该进程两次,因为它给出了地址正在使用中的错误,我仍然可以在任务管理器中看到该进程。

这是我尝试这样做的方法,但似乎缺少一些东西来完全杀死所有进程:

class Program
{
    static Process cmd;

    static async Task Main(string[] args)
    {
        AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;

        var startInfo = new ProcessStartInfo("cmd.exe")
        {
            UseShellExecute = false,
            RedirectStandardInput = true,
            CreateNoWindow = true,
        };

        cmd = new Process { StartInfo = startInfo };

        cmd.Start();

        using (cmd)
        {
            cmd.StandardInput.WriteLine($"cd C:/Project/publish");
            cmd.StandardInput.WriteLine($"dotnet WebAPI.dll");
            cmd.WaitForExit();
        }
    }

    static void CurrentDomain_ProcessExit(object sender, EventArgs e)
    {
        Process.GetProcessById(cmd.Id).Kill();
        Environment.Exit(0);
    }
}

【问题讨论】:

  • “它无法杀死所有进程”是什么意思?您的服务是否再次产生其他进程?那么这将无济于事,因为 kill 不是递归的。我建议您考虑一个很好地终止所有进程的解决方案。杀死应该始终是最后的选择,因为它可能会导致数据丢失。
  • @mjwills,您说:“启动 cmd.exe 来运行 dotnet 似乎很奇怪。您应该直接启动 dotnet。”那么,直接运行dotnet 是什么意思?
  • @mjwills - 效果很好!不知道为什么我之前没有想到这一点 :-) 我认为最好发布带有完整解决方案的代码示例。你要我发还是你愿意?
  • @mjwills,已发给您的学分。感谢您的帮助。

标签: c# asp.net-core-2.0


【解决方案1】:

根据@mjwills 的建议,我已将流程更新如下:

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,
                WorkingDirectory = "C:/Project/publish",
                Arguments = "WebAPI.dll",
                CreateNoWindow = true
            }
        };
        using (webAPI)
        {
            webAPI.Start();
            webAPI.WaitForExit();
        }
    }

    static void CurrentDomain_ProcessExit(object sender, EventArgs e)
    {
        webAPI.Close();
    }
}

【讨论】:

  • 如果我没记错的话 webAPI.Close();仅释放与此进程关联的所有资源。那么你是如何杀死子进程的。
  • @RPrashant,我不确定我是否理解您的问题。 webAPI.Close() 表示当启动webAPI 进程的(父)控制台应用程序退出时,(子)webAPI 进程也将关闭。
  • 但在我的情况下它没有关闭子进程。我仍然可以在任务管理器中看到该进程。
  • @RPrashant,您可以使用第二种方法,通过从子进程监视父进程来执行此操作,如下所示:Process process = Process.GetProcessById(PARENT_PROCESS_ID); Task.Run(() => process.WaitForExit()).ContinueWith(t => Environment.Exit(-1)); 为此,您需要将父进程 ID 传递给子进程。
  • 我已经问了我的问题here。你能检查一下吗
【解决方案2】:

您可以使用当前进程的Kill() 方法终止应用程序。

Startup.cs

        public void Configure(IHostApplicationLifetime appLifetime)
        {
            //...

            appLifetime.ApplicationStarted.Register(() =>
            {
                Console.WriteLine("Press Ctrl+C to shut down.");
            });

            appLifetime.ApplicationStopped.Register(() =>
            {
                Console.WriteLine("Shutting down...");
                System.Diagnostics.Process.GetCurrentProcess().Kill();
            });
        }

Program.cs

在构建主机时不要忘记使用UseConsoleLifetime()

Host.CreateDefaultBuilder(args).UseConsoleLifetime(opts => opts.SuppressStatusMessages = true);

【讨论】:

    【解决方案3】:
     class first_class{
    
    static Process[] cmd=new Process[size];
          int main(){
               cmd[0] = new Process { StartInfo = startInfo };
    
               cmd[0].Start();
          }
    };
    

    ================================================

    ref class otherClass{
    
    first_class::cmd[0].Kill();
    
    };
    

    【讨论】:

      猜你喜欢
      • 2018-02-20
      • 1970-01-01
      • 1970-01-01
      • 2020-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多