gpt4 book ai didi

强制终止子进程的 Java 工具/方法

转载 作者:搜寻专家 更新时间:2023-10-30 19:44:53 25 4
gpt4 key购买 nike

我正在寻找一个允许我强制终止的 Java 工具/包/库一个子进程。

此工具/包/库必须在 Windows 平台上工作(强制)。需要对 Linux/Unix 的支持。

我的问题

我的 Java 代码创建了一个子进程,它不会对杀死子进程的标准 Java 方法:process.destroy(),以及,因为我没有 child 的源代码,所以我无法将其编程为更好地处理终止请求。

我试过关闭子进程的错误输入和输出流在调用 destroy() 之前,并且没有任何效果。

我什至尝试将 ctrlBreak 信号 (char=3) 直接传递给child.getOutputStream(),并再次收到相同的结果。

我最终设法找到的解决方法是:

  1. 在子进程创建时获取子进程的 PID 这可以在 Windows 中通过区分进程列表来完成 子进程创建前后 (getRuntime().exec("tasklist/v"))

  2. 使用 child 的 PID 发出强制终止系统命令
    在 Windows 中:getRuntime().exec("taskkill/pid "+ childPid + "/f")

但是-这是我不想调试和维护的复杂代码,加上问题毫无疑问,许多其他 Java 开发人员以前遇到过它本身,这让我希望这样的 Java 工具/包/库已经存在。

我只是不知道它的名字...

PS: 我的子进程是由 Runtime.getRuntime().exec(cmd) 创建的,但是我使用 ProcessBuilder 得到了相同的行为。

最佳答案

有一种使用 Java JNA 来执行此操作的更精简的方法。

这绝对适用于 Windows 和 Linux,我认为您也可以对其他平台执行相同的操作。

Java进程处理最大的问题是缺少获取进程id的方法,用untime.getRuntime().exec()启动。

假设你得到了一个进程的 pid,你总是可以在 linux 中启动一个 kill -9 命令,或者使用类似的方法在 windows 中杀死一个进程。

这是一种为 linux 本地获取进程 ID 的方法(借用自 selenium 框架,:)),在 JNA 的帮助下,这也可以为 windows 完成(使用本地 Windows API 调用)。

要使其工作(对于 Windows),您首先必须在 JAVA NATIVE ACCESS (JNA): Downloads 获取 JNA 库或从 maven 获取

看下面的代码,它将获取一个(在本例中为 windows)程序的 pid(大部分代码实际上是让 java 程序正常运行的碎片):

import com.sun.jna.*;
import java.lang.reflect.Field;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Main {

static interface Kernel32 extends Library {

public static Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);

public int GetProcessId(Long hProcess);
}

public static void main(String[] args) {
try {
Process p;

if (Platform.isWindows())
p = Runtime.getRuntime().exec("cmd /C ping msn.de");
else if (Platform.isLinux())
p = Runtime.getRuntime().exec("cmd /C ping msn.de");

System.out.println("The PID: " + getPid(p));

int x = p.waitFor();
System.out.println("Exit with exitcode: " + x);

} catch (Exception ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}

public static int getPid(Process p) {
Field f;

if (Platform.isWindows()) {
try {
f = p.getClass().getDeclaredField("handle");
f.setAccessible(true);
int pid = Kernel32.INSTANCE.GetProcessId((Long) f.get(p));
return pid;
} catch (Exception ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
} else if (Platform.isLinux()) {
try {
f = p.getClass().getDeclaredField("pid");
f.setAccessible(true);
int pid = (Integer) f.get(p);
return pid;
} catch (Exception ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
else{}
return 0;
}
}

希望这会有所帮助,;)...

关于强制终止子进程的 Java 工具/方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4912282/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com