强制杀死子进程的Java工具/方法
我正在寻找一个Java工具/程序包/库,该工具可以强制杀死子进程。
该工具/软件包/库必须在Windows平台上运行(强制性)。需要对Linux / Unix的支持。
回答:
我的Java代码创建了一个子进程,该子进程不会对杀死子进程的标准Java方法做出反应:process.destroy(),并且由于我没有子进程的源代码,因此我无法对其进行编程以更好地处理终止请求。
我尝试在调用destroy()之前关闭子进程的错误输入和输出流,但没有任何效果。
我什至尝试将ctrlBreak信号(char = 3)直接传递给child.getOutputStream(),并再次收到相同的结果。
我终于设法找到的解决方法是:
在创建孩子的PID时获取它的PID可以在Windows中通过创建孩子的前后(
getRuntime().exec("tasklist /v")
)的进程列表进行比较来完成在Windows中使用孩子的PID发出强制终止系统命令:
getRuntime().exec("taskkill /pid " + childPid + "
/f")
但是-这是我不希望调试和维护的复杂代码,而且毫无疑问,许多其他Java开发人员以前都曾遇到过这个问题,这使我希望这样的Java工具/软件包/库已经存在存在。
我只是不知道它的名字…
PS:我的子流程是由创建的Runtime.getRuntime().exec(cmd)
,但是使用ProcessBuilder会得到相同的行为。
回答:
使用Java JNA可以找到一种更精简的方法。
这绝对适用于Windows和Linux,我认为您也可以在其他平台上执行相同的操作。
Java进程处理的最大问题是缺少一种方法来获取以untime.getRuntime()。exec()开始的进程的进程ID。
假设您已获得进程的pid,则始终可以在linux中启动kill -9命令,或使用类似的方法在Windows中终止进程。
这是一种本地获取linux进程ID的方法(从selenium框架中借来的:)),借助JNA,也可以在Windows上完成此操作(使用本地Windows
API调用)。
为此(对于Windows),必须首先从JAVA NATIVE ACCESS(JNA)获得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工具/方法 的全部内容, 来源链接: utcz.com/qa/408167.html