在使用java过程中,很多人可能遇到过这样的问题,当我们通过cmd.exe执行命令的时候,如下:
Runtime rt = Runtime.getRuntime();
Process process
= rt.exec(cmd);
java会在后台进程中开启一个cmd.exe的进程,当我们想要杀死该进程的时候使用process.destroy(),只能杀死java程序启动的cmd.exe,无法杀死cmd.exe创建的进程,也就是说无法杀死进程树,基于以上问题,我的处理方式是:
(1)获取process进程ID;
(2)通过taskkill杀死进程树;
privatestatic void killProcessTree(Process process)
{
try {
Field f =process.getClass().getDeclaredField("handle");
f.setAccessible(true);
long handl =f.getLong(process);
Kernel32kernel = Kernel32.INSTANCE;
WinNT.HANDLEhandle = new WinNT.HANDLE();
handle.setPointer(Pointer.createConstant(handl));
int ret =kernel.GetProcessId(handle);
Long PID =Long.valueOf(ret);
String cmd =getKillProcessTreeCmd(PID);
Runtime rt =Runtime.getRuntime();
ProcesskillPrcess = rt.exec(cmd);
killPrcess.waitFor();
killPrcess.destroy();
}catch(Exception e)
{
e.printStackTrace();
}
}
privatestatic String getKillProcessTreeCmd(Long Pid)
{
Stringresult = "";
if(Pid !=null)
result ="cmd.exe /c taskkill /PID "+Pid+" /F /T ";
returnresult;
}
这里需要引入两个jar包,分别为jna.jar和platform.jar,下载地址:https://java.net/projects/jna/downloads/directory/3.3.0
这样可以很方便的获取到自己创建的Process的PID,并且在销毁的时候也可以把子进程杀死。
引用:
https://github.com/flapdoodle-oss/de.flapdoodle.embed.process/blob/master/src/main/java/de/flapdoodle/embed/process/runtime/Processes.java