Java ProcessBuilder process.destroy() 不会杀死 winXP 中的子进程

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/801609/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 13:52:14  来源:igfitidea点击:

Java ProcessBuilder process.destroy() not killing child processes in winXP

java

提问by Derek

I have a java app that uses ProcessBuilderto prepare an operating system command and gives me a Processobject. (The actual os command is rsync over ssh using cygwin).

我有一个 Java 应用程序,用于ProcessBuilder准备操作系统命令并给我一个Process对象。(实际的 os 命令是使用 cygwin 通过 ssh 进行 rsync)。

This is working well in Windows, however if I want to stop the process using process.destroy()it will not kill the child ssh and rsync processes..... I have to manually kill them using the windows task manager..

这在 Windows 中运行良好,但是如果我想停止使用process.destroy()它的进程不会杀死子 ssh 和 rsync 进程.....我必须使用 Windows 任务管理器手动杀死它们..

Is it possible to get the OutputStreamof the process and send a ctrl-c somehow before I call destroy();?

是否有可能OutputStream在我打电话之前获得进程并以某种方式发送 ctrl-c destroy();

If anyone has any ideas on a workaround it would be great. Thanks, D

如果有人对解决方法有任何想法,那就太好了。感谢:D

采纳答案by Elazar Leibovich

I also think that emulating Ctrl-C in order to kill ssh entirely is problematic.

我还认为模拟 Ctrl-C 以完全杀死 ssh 是有问题的。

What I would do, is one of the following approaches. Either use windows commands to find out who are ssh's sons (which is a little bit problematic, since you need to know your current pid in order to recieve your own children-processes). I believe pstoolsof sysinternals is a good command-line tool that should enable you to track orphan processes. See this examplefor controlling windows processes either with taskList.exe(which can give you its output in CSV format BTW) or by executing a special VBScript.

我会做的是以下方法之一。要么使用 windows 命令找出谁是 ssh 的儿子(这有点问题,因为您需要知道您当前的 pid 才能接收您自己的子进程)。我相信sysinternals 的pstools是一个很好的命令行工具,它应该使您能够跟踪孤立进程。请参阅此示例以使用taskList.exe(它可以以 CSV 格式 BTW 为您提供其输出)或通过执行特殊的 VBScript来控制 Windows 进程。

The second approach is using a java library such as winpto execute and control the ssh process. I believe you'd be able to list all its children and forcibly kill them if sending the correct message would not suffice. This would be my preferred approach. Please note that the killRecursivelymethod does exactly what you want.

第二种方法是使用诸如winp 之类的java 库来执行和控制ssh 进程。我相信如果发送正确的消息还不够,你可以列出它的所有孩子并强行杀死他们。这将是我的首选方法。请注意,killRecursively方法完全符合您的要求。

Please note that those approaches should not render your application windows only. You can encapsulate those in a class that would run differently on Windows and linux machines.

请注意,这些方法不应仅呈现您的应用程序窗口。您可以将它们封装在一个在 Windows 和 Linux 机器上以不同方式运行的类中。

Please note I didn't try to gain a fine-grained control on windows processes with, so I'm not sure how mature would those solutions I found are.

请注意,我没有尝试对 Windows 进程进行细粒度控制,所以我不确定我找到的这些解决方案有多成熟。

回答by Brian Agnew

I'm not sure what Process.destroy() does under the covers (sends a signal or similar?).

我不确定 Process.destroy() 在幕后做了什么(发送信号或类似的?)。

What you may find works better is to invoke your ssh/rsync within a shell script, and have that return a process id on stdout, and then when you want to kill the process, perform a /bin/killwith that process id. A little messy, but perhaps more reliable.

您可能会发现更好的方法是在 shell 脚本中调用您的 ssh/rsync,并在 stdout 上返回一个进程 ID,然后当您想终止该进程时,/bin/kill使用该进程 ID执行 a 。有点乱,但也许更可靠。

Note you can /bin/killwith SIGTERM, and SIGKILL if it's particularly stubborn.

请注意/bin/kill,如果它特别顽固,您可以使用 SIGTERM 和 SIGKILL。