【问题标题】:Stop command line process started in C# on Close of Application在关闭应用程序时停止在 C# 中启动的命令行进程
【发布时间】:2018-12-20 12:00:29
【问题描述】:

我已经在我的 C# 应用程序中的按钮单击事件上启动了一个进程,如下所示,

System.Diagnostics.Process process = new System.Diagnostics.Process();
private void btnOpenPort_Click(object sender, RoutedEventArgs e)
{
    System.Diagnostics.ProcessStartInfo startInfo = new 
    System.Diagnostics.ProcessStartInfo();
    startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
    startInfo.FileName = "http-server";
    // startInfo.Arguments = "/C http-server -p 8765";
    this.process.StartInfo = startInfo;
    this.process.Start();                     
}

现在,我想在应用程序窗口关闭时停止这个命令行进程。就像我在命令提示符中写一个命令一样,我通常按 Ctrl + C 来停止执行。

编辑:我有这个事件,当点击关闭按钮时触发。

private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    Int32 result = DllWrapper.HdsDestroy();
    MessageBox.Show("Destroy result = " + (result == 0 ? "Success" : "Fail"));
}

我在 Internet 上找到了一个解决方案,SendKeys,但我无法理解。 PS:这可能是一些问题的重复,但其中一些对我不起作用。

提前致谢

【问题讨论】:

  • 嘿@mjwills,我刚刚发现process.Start() 启动了两个进程,一个cmd.exe 和NodeJs,在process.Kill() 上它只杀死了cmd.exe。所以服务器还在运行!
  • 是的。 startInfo.FileName = "http-server"; 使用这个。
  • 在这种情况下,找到nodejs 进程并杀死它。

标签: c# windows command-line process


【解决方案1】:

调用process.Kill();method,将停止相关进程。

【讨论】:

    【解决方案2】:

    在此事件处理程序中处理应用程序退出事件并关闭进程。

    public static event EventHandler ApplicationExit

    示例:

    // Attache Handler to the ApplicationExit event.
    Application.ApplicationExit += new EventHandler(this.OnApplicationExit);
    

    处理程序:

    private void OnApplicationExit(object sender, EventArgs e) {
    
        try {
            // Ignore any errors that might occur while closing the file handle.
            process.Kill();
        } 
        catch {}
    }
    

    【讨论】:

    • 有一个关闭按钮单击事件并在该事件中尝试了此操作,但该过程仍然没有停止。
    • 那么在杀死进程的过程中可能会出现一些异常。你能分享一下异常日志吗?
    • 不,没有异常发生。
    • @lazzy_ms:如果每个答案都不能解决您的问题,您不应该随机投票。只是不要投票并将其留在那里。
    【解决方案3】:

    将此行添加到Form的构造函数中:

    Application.ApplicationExit += (s, ev) => process.Kill();
    

    编辑

    使用此代码:

    if (process.MainWindowHandle != IntPtr.Zero)
        process.CloseMainWindow(); // this Closes process by sending a close message to its main window.
    else
        process.Kill(); // this kills Hidden window
    process.Close(); // Frees all resources that are associated with process.
    

    【讨论】:

    • 有一个关闭按钮单击事件并在该事件中尝试了process.Kill(),但该过程仍然没有停止。
    • @lazzy_ms:如果每个答案都不能解决您的问题,您不应该随机投票。只是不要投票并将其留在那里。
    • 我没有。别人做了。
    【解决方案4】:

    感谢@mjwills 指导我。

    后来,我发现process.Start() 在这种情况下启动了两个不同的进程。一个是 cmd.exe,另一个是 node.exe

    process.Kill() 只杀死 cmd.exe。所以,我发现我必须找到那个 node.exe 进程并杀死它。

    我有两个解决方案:

    1.这可能会停止所有名为 node.exe 的进程,但现在,这对我有用。

    foreach(var node in Process.GetProcessesByName("node"))
    {
       node.Kill();
    }
    

    2.正如我在问题中提到的,使用SendKeys.SendWait("^(C)");

    [DllImport("User32.dll")]
    static extern int SetForegroundWindow(IntPtr point);
    

    导入此 dll 文件以获取前台的命令行窗口。然后我像这样修改了关闭按钮事件。

    private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
    {   
        Process proc = Process.GetProcessById(pid);
        IntPtr h = proc.MainWindowHandle;
        SetForegroundWindow(h);
        SendKeys.SendWait("^(C)");          
    }
    

    【讨论】:

      【解决方案5】:

      取决于您是否显示窗口。 如果您要显示一个窗口,请使用:

      process.CloseMainWindow();
      

      如果不是,你可以搜索进程名并关闭它:

      System.Diagnostics.Process.GetProcessesByName("Process Name").First().Kill();
      System.Diagnostics.Process.GetProcessesByName("Process Name").First().Close();
      

      为了获得更好的结果,尝试将前面的代码放在一个 try-catch 块中

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-15
        • 1970-01-01
        相关资源
        最近更新 更多