如何在Java中终止一个进程 process.destroy()

4
我曾尝试使用process.destroy()方法来终止一个进程。经过一些研究,我了解到有时它不起作用,所以我尝试使用"Taskkiller"来杀死进程。
使用以下代码: Java工具/方法强制终止子进程 我通过进程运行cmd,并通过cmd(bat文件)调用jar。我可以通过taskkill停止cmd。但我找不到停止jar的方法。
编辑:
我找到了一种方法。在进程开头获取进程ID。

你能否直接通过ProcessBuilderRuntime.exec()从你的应用程序中运行jar,而不是使用批处理文件来运行它?如果可以的话,你只需要调用destroy()方法就可以了。 - dic19
Dic19所说的应该可以行得通。我看到的问题是你正在创建一个进程来创建另一个进程。我没有看到任何直接获取第二个进程句柄的简单方法。虽然这是可行的,但更简单的方法是消除中间人并直接启动第二个进程。目前你正在做的应该可以行得通。 - MadConan
是的,没错,但我正在通过批处理文件调用两个进程。 - Rane
回滚了编辑,因为其中一些更改是不正确的,除非OP实际上是指“command”,而不是“cmd”。这是模棱两可的-第一次出现时似乎是“command”的缩写,但第二次出现时似乎是指cmd。请澄清。(无论如何,taskkill是一个实用程序的名称,不应该被拆分成两个单词。) - Adi Inbar
3
顺便提一下,如果你找到了解决方案,请把它发布为答案而不是编辑,并提供更多细节,以便于未来的读者有用。 - Adi Inbar
@Rane 你好,你考虑过执行 Adi Inbar 建议的事情吗? - Joe DF
1个回答

0

我修改了程序,直接启动了第二个进程。

然后我使用以下方法销毁了该进程。

private static void destroyProcess(final Process process) {

    if (process != null) {

        Field field;
        final Runtime runtime = Runtime.getRuntime();

        final Class<? extends Process> getClass = process.getClass();
        if (JAVA_LANG_UNIX_PROCESS.equals(getClass.getName())) {
            // get the PID on unix/linux systems
            try {
                field = getClass.getDeclaredField("pid");
                field.setAccessible(true);
                final Object processID = field.get(process);
                final int pid = (Integer) processID;
                // killing the task.

                    runtime.exec("kill -9 " + pid);
                } catch (IOException e) {
                    LOGGER.error("Error in Killing the process:" + e);
                } catch (SecurityException e) {
                    LOGGER.error("Error in Killing the process:" + e);
                } catch (NoSuchFieldException e) {
                    LOGGER.error("Error in Killing the process:" + e);
                } catch (IllegalArgumentException e) {
                    LOGGER.error("Error in Killing the process:" + e);
                } catch (IllegalAccessException e) {
                    LOGGER.error("Error in Killing the process:" + e);
                }
        }

        final String classGetName = getClass.getName();
        if (JAVA_LANG_WIN32_PROCESS.equals(classGetName) || JAVA_LANG_PROCESS_IMPL.equals(getClass.getName())) {
            // determine the pid on windowsplattforms
            process.destroy();
            try {
                field = getClass.getDeclaredField("handle");
                field.setAccessible(true);
                final int pid = Kernel32.INSTANCE.GetProcessId((Long) field.get(process));
                // killing the task.
                runtime.exec("taskkill " + pid);

            } catch (SecurityException e) {
                LOGGER.error("Error in Killing the process:" + e);
            } catch (NoSuchFieldException e) {
                LOGGER.error("Error in Killing the process:" + e);
            } catch (IOException e) {
                LOGGER.error("Error in Killing the process:" + e);
            } catch (IllegalArgumentException e) {
                LOGGER.error("Error in Killing the process:" + e);
            } catch (IllegalAccessException e) {
                LOGGER.error("Error in Killing the process:" + e);
            }

        }
    }
}

/**
 * 
 * This interface use to kernel32.
 */
static interface Kernel32 extends Library {

    /**
     *
     */
    Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);

    /**
     * 
     * GetProcessId.
     * 
     * @param hProcess
     *            hProcess
     * @return return the PID.
     */
    int GetProcessId(Long hProcess);
    // NOTE : Do not change the GetProcessId method name.
}

我从以下链接得到了帮助:http://www.golesny.de/p/code/javagetpid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接