19

本质上,我正在制作一个小程序,它将安装一些软件,然后运行一些基本命令来准备该程序。然而,正在发生的事情是程序开始安装,然后立即进入以下行(注册、更新等)。当然,在完全安装之前不会发生这种情况,所以我想找到一种在运行第二个进程之前等待第一个进程的方法。例如,

    Main.say("Installing...");
    Process p1 = Runtime.getRuntime().exec(dir + "setup.exe /SILENT");
    //Wait here, I need to finish installing first!
    Main.say("Registering...");
    Process p2 = Runtime.getRuntime().exec(installDir + "program.exe /register aaaa-bbbb-cccc");
    Main.say("Updating...");
    Process p4 = Runtime.getRuntime().exec(installDir + "program.exe /update -silent");
4

4 回答 4

33

打电话Process#waitFor()。它的 Javadoc 说:

如有必要,使当前线程等待,直到此Process对象表示的进程终止。

奖励:您获得子流程的退出值。因此,您可以检查它是否使用 code 成功退出0,或者是否发生错误(非零退出代码)。

于 2013-07-31T13:56:44.637 回答
8

你可以使用Process.waitFor()方法

医生说

如有必要,使当前线程等待,直到此 Process 对象表示的进程终止。如果子进程已经终止,则此方法立即返回。如果子进程尚未终止,则调用线程将被阻塞,直到子进程退出。

于 2013-07-31T13:56:29.487 回答
5

如果您正在运行返回一个很长的响应字符串的系统命令,则标准输入缓冲区会填满并且进程似乎挂起。这发生在我的 sqlldr 身上。如果情况确实如此,那么只需在进程运行时从标准输入读取。

    try {
        ProcessBuilder pb = new ProcessBuilder("myCommand");
        Process p = pb.start();
        BufferedReader stdInput = new BufferedReader(new 
                InputStreamReader(p.getInputStream()));

        BufferedReader stdError = new BufferedReader(new 
                InputStreamReader(p.getErrorStream()));
        StringBuffer response = new StringBuffer();
        StringBuffer errorStr = new StringBuffer();
        boolean alreadyWaited = false;
        while (p.isAlive()) {
            try {
                if(alreadyWaited) {

                    // read the output from the command because
                    //if we don't then the buffers fill up and
                    //the command stops and doesn't return
                    String temp;

                    while ((temp = stdInput.readLine()) != null) {
                        response.append(temp);
                    }


                    String errTemp;
                    while ((errTemp = stdError.readLine()) != null) {
                        errorStr.append(errTemp);
                    }                                                   
                }
                Thread.sleep(1000);
                alreadyWaited = true;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            logger.debug("Response is " + response);
            logger.debug("Error is: " + errorStr);
        }

    } catch (IOException e) {
        logger.error("Error running system command", e);
    }
于 2018-07-15T16:10:30.770 回答
3

包括waitFor()。在您的情况下,您的代码将如下所示。

    Main.say("Installing...");
    Process p1 = Runtime.getRuntime().exec(dir + "setup.exe /SILENT");
    p1.waitFor()
    Main.say("Registering...");
    Process p2 = Runtime.getRuntime().exec(installDir + "program.exe /register aaaa-bbbb-cccc");
    Main.say("Updating...");
    Process p4 = Runtime.getRuntime().exec(installDir + "program.exe /update -silent");
于 2017-11-29T08:32:28.167 回答