“杀死进程树”在 Windows 上使用 Java

发布于 2024-12-06 08:22:01 字数 593 浏览 4 评论 0原文

我有一个 Java Webstart 进程,它是 Windows 批处理脚本的一部分。在本例中,我在批处理脚本中使用 javaws 命令。 使用“apache commons exec”以编程方式调用此匹配脚本(start.bat)。在某些情况下,javaws 调用的 java 进程会挂起,我必须终止从批处理脚本 start.bat 开始的整个进程线程。 是否有一种编程方法可以通过 apache commons exec 杀死整个进程树?

我尝试过使用“execWatchdog.destroyProcess();”在“start.bat”脚本上。然而,它只会杀死 start.bat 进程,而不是整个进程树。

有没有办法通过 apache-commons-exec 或类似的代码杀死整个进程树?

我见过这个问题 执行相当于“Kill Process” Windows 上的 C++ 中的“树”,在 C++ 中执行等效任务。我想知道是否有人实现了通过JNI调用windows本机系统调用。

I have a Java webstart process that is part of a windows batch script. I'm using the javaws command in a batch script in this case.
This match script ( start.bat) is invoked programatically using the "apache commons exec". Under some conditions the java process invoked by javaws hangs and I'd have to kill the entire process thread starting from the batch script start.bat.
Is there a programatic way of doing killing an entire process tree through apache commons exec?

I've tried using the "execWatchdog.destroyProcess();" on the "start.bat" script. However it only kills the start.bat process and not the entire process tree.

Is there a way of killing the entire process tree through apache-commons-exec or a similar code?

I've seen this question Performing equivalent of "Kill Process Tree" in c++ on windows that performs an equivalent task in c++. I'm wondering if anyone has implemented calling windows native system calls through JNI.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

自此以后,行同陌路 2024-12-13 08:22:01

终于得到了一些可行的东西,尽管这是一种迂回的方式。

Apache Commons Exec API 包含返回 java.lang.Process 对象的 CommandLauncher 类。感谢链接

这里链接从中获取Windows进程ID java.lang.Process。这使用 JNA 库。

最后是进程 ID,这里是杀死进程树的命令字符串
//String KillCmd = "taskkill /F /T /PID " + JNAHandler.getPid(process);

Finally got something workable even though its a roundabout way.

Apache Commons Exec API contains the CommandLauncher class that returns a java.lang.Process object. Thanks to the link

Here the link to get the windows Process Id from a java.lang.Process. This uses the JNA libraries.

Finally with the Process Id, here the command string that kills the process tree
//String killCmd = "taskkill /F /T /PID " + JNAHandler.getPid(process);

似狗非友 2024-12-13 08:22:01

不幸的是,正如您所发现的,没有一种纯 Java 方法可以做到这一点。您必须求助于本机命令或 JNI 库,所有这些都依赖于平台,并且比纯 Java 解决方案更复杂。

也许值得对 Java bug 数据库中的相关 bug 进行投票:https://bugs。 java.com/bugdatabase/view_bug?bug_id=4770092

如果幸运的话,我们可以说服 Java 开发人员相信 Java 8 值得修复子进程的不良处理问题。

Unfortunately, as you've discovered, there isn't a pure Java way of doing this. You'll have to resort to native commands or JNI libraries, all of which are platform-dependent and more complex than a pure Java solution would be.

It may be worth upvoting the relevant bug in the Java bug database: https://bugs.java.com/bugdatabase/view_bug?bug_id=4770092

With luck we can persuade the Java developers that the poor handling of subprocesses is worth fixing for Java 8.

软糖 2024-12-13 08:22:01

据我所知,commons-exec 中没有这样的选项。甚至不可能获得您刚刚启动的任何进程的 PID。您可以在 bash 脚本中捕获终止信号,并让处理程序在脚本进程被终止时终止子进程。

As far as I know, there's no such option in commons-exec. It's not even possible to obtain the PID of whatever process you just started. You could trap the kill signal within your bash script, and have the handler kill the subprocess(es) when the script process is killed.

宣告ˉ结束 2024-12-13 08:22:01

Java 版本 9 开始,
Java 提出了可以查询和终止主进程及其子进程的功能。
查询子进程的代码片段

import java.io.IOException;

public class ProcessTreeTest {
   public static void main(String args[]) throws IOException {
      Runtime.getRuntime().exec("cmd");
     
      System.out.println("Showing children processes:");
      ProcessHandle processHandle = ProcessHandle.current();
      processHandle.children().forEach(childProcess ->
              System.out.println("PID: " + childProcess.pid() + " Command: " + childProcess.info().command().get()));
     
      System.out.println("Showing descendant processes:");
      processHandle.descendants().forEach(descendantProcess ->
              System.out.println("PID: " + descendantProcess.pid() + " Command: " +   descendantProcess.info().command().get()));
   }
}

要杀死进程及其子进程,Java9 有 API
遍历进程的所有children,并对每个进程调用destroy

例如:在您的情况下,您从 apache-commons 获取 Process 对象,然后尝试以下操作代码

Process child = ...;
kill (child.toHandle());

public void kill (ProcessHandle handle)
{
    handle.descendants().forEach((child) -> kill(child));
    handle.destroy();
}

参考:

https://docs.oracle.com/javase/9​​/docs/api/java/lang/ProcessHandle.html

https://www.tutorialspoint.com/how-to-traverse-a-process-tree-of-process-api-in-java-9

如何从 Java 终止进程树?

注意 - 我还没有尝试过这个功能,只是阅读了有关 Java9 和
发现这里分享很有帮助。

Java Version 9 Onwards,
Java has come up with feature that can query and kill the main process and its descendants.
A code snippet to query about the child processes

import java.io.IOException;

public class ProcessTreeTest {
   public static void main(String args[]) throws IOException {
      Runtime.getRuntime().exec("cmd");
     
      System.out.println("Showing children processes:");
      ProcessHandle processHandle = ProcessHandle.current();
      processHandle.children().forEach(childProcess ->
              System.out.println("PID: " + childProcess.pid() + " Command: " + childProcess.info().command().get()));
     
      System.out.println("Showing descendant processes:");
      processHandle.descendants().forEach(descendantProcess ->
              System.out.println("PID: " + descendantProcess.pid() + " Command: " +   descendantProcess.info().command().get()));
   }
}

To kill the process and its children, Java9 has API
Iterate through all the children of the process and call destroy on each of them

For Example : As in your case you are getting Process object from apache-commons, then try out following code

Process child = ...;
kill (child.toHandle());

public void kill (ProcessHandle handle)
{
    handle.descendants().forEach((child) -> kill(child));
    handle.destroy();
}

References :

https://docs.oracle.com/javase/9/docs/api/java/lang/ProcessHandle.html

https://www.tutorialspoint.com/how-to-traverse-a-process-tree-of-process-api-in-java-9

How do i terminate a process tree from Java?

Note - I have not tried this feature, Just reading about Java9 and
found helpful to share here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文