【发布时间】:2019-04-22 06:54:57
【问题描述】:
环境
Windows 上的 jdk8
步骤
- 使用
ProcessBuilder创建一个Process实例,并使用进程的输出执行一些任务。 - 致电
waitFor()等待此过程完成。 - 使用jna+cmd强制终止进程。我在
finally块中执行此操作,以确保进程始终终止。
Field f = process.getClass().getDeclaredField("handle");
f.setAccessible(true);
long handleValue = f.getLong(process);
WinNT.HANDLE handle = new WinNT.HANDLE();
handle.setPointer(Pointer.createConstant(handleValue));
Kernel32 kernel = Kernel32.INSTANCE;
int pid = kernel.GetProcessId(handle);
Process killPr = Runtime.getRuntime().exec("cmd /c taskkill /pid " + pid + " /f /t");
killPr.waitFor();
killPr.destroy();
问题
执行上述步骤是否安全?我会在第 3 步中杀死另一个不相关的进程吗?我调试并注意到ProcessImpl 的handle 值在进程退出后仍然有效。我担心windows系统会在退出真实进程但进程对象没有被jvm回收时重用相同的句柄。
【问题讨论】:
-
无论如何,当您通过 JNA 使用本机调用时,为什么不直接调用
TerminateProcess而不是启动运行命令行解释器的外部进程,执行taskkill命令最终执行所需的操作打电话? -
@Holger 我不确定
TerminateProcess是否也会杀死所有子进程。 api 文档说此方法将终止指定进程及其所有线程。taskkill的/t参数将执行此操作,请参阅 this page -
好吧,我对 Windows API 没有那么深入,但很明显,
taskkill必须调用一个函数,因为taskkill命令只是软件。因此,无论taskkill使用什么函数,直接通过 JNA 调用都是更简单的选择。最后,您想销毁Process,如果您认为,在其上调用destroy()是不够的,那么启动新的Process并最终依靠在其上调用destroy()是一种扭曲的解决方案。
标签: windows winapi java-8 process win32-process