[英]Run bat file in Java and wait 2
这是我另一个问题的跟进问题: 在Java中运行bat文件并等待
我将其作为一个单独的问题发布的原因是,我已经问过的问题得到了正确回答。 通过一些研究,我发现我的问题是我所遇到的问题所独有的,因此我决定创建一个新问题。 由于它们关系密切,因此请先阅读该问题,然后再继续进行此问题。
运行建议的代码会在waitFor调用时阻止程序。 经过一番研究,我发现,如果您的进程具有需要处理的输出,则waitFor方法会阻塞,因此您应该首先清空输出流和错误流。 我做了这些事情,但我的方法仍然受阻。 然后,我发现一个建议,可以在等待exitValue方法返回过程的退出值时简单地循环并处理抛出的异常(如果不是),暂停一会儿,以免消耗掉所有CPU。 我这样做:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Test {
public static void main(String[] args) {
try {
Process p = Runtime.getRuntime().exec(
"cmd /k start SQLScriptsToRun.bat" + " -UuserName -Ppassword"
+ " projectName");
final BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
final BufferedReader error = new BufferedReader(new InputStreamReader(p.getErrorStream()));
new Thread(new Runnable() {
@Override
public void run() {
try {
while (input.readLine()!=null) {}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
while (error.readLine()!=null) {}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
int i = 0;
boolean finished = false;
while (!finished) {
try {
i = p.exitValue();
finished = true;
} catch (IllegalThreadStateException e) {
e.printStackTrace();
try {
Thread.sleep(500);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
System.out.println(i);
} catch (IOException e) {
e.printStackTrace();
}
}
}
但是我的过程不会结束! 我不断收到此错误:
java.lang.IllegalThreadStateException: process has not exited
关于为什么我的流程无法退出的任何想法? 还是您有任何库建议使用适当的批处理文件,然后等待执行完成?
使用/c
开关而不是/k
来启动cmd
并摆脱start
:
Process p = Runtime.getRuntime().exec(
"cmd /c SQLScriptsToRun.bat" + " -UuserName -Ppassword"
+ " projectName");
/k
告诉cmd
:“运行该命令,然后保持打开状态”, /c
则显示“运行该命令,然后退出”。
/k
供交互式使用,您需要初始化批处理文件,然后仍使用控制台。
但是,这里的主要问题是您正在使用start
创建另一个进程 。 要运行批处理文件,这是完全没有必要的,并且可以防止您知道批处理何时完全运行,因为Java引用了您启动的原始cmd
进程,而不是您使用start
生成的cmd
进程。
原则上,现在看起来如下所示:
cmd
并指示其运行start foo.bat
并保持打开状态以进行交互式输入( /k
) Java存储进程ID(PID 42),以便以后引用该进程
cmd
(PID 42)启动 cmd
(PID 42)运行start foo.bat
start foo.bat
启动cmd
另一个实例,因为这是运行批处理文件时应执行的操作
cmd
(PID 57005)启动 cmd
(PID 57005)运行foo.bat
cmd
(PID 57005)退出(这表示您想了解的事件) cmd
(PID 42)显示提示并听从等待输入(对于他们而言,未知的提示是用户从未看到过提示,并且永远不会输入...但是cmd
(PID 42)等待...) Java喜欢知道该过程是否完成并检查PID 42
您想要的(以及上述更改将完成的工作)是:
cmd
并指示其运行foo.bat
并在运行命令( /c
)后关闭 Java存储进程ID(PID 42),以便以后引用该进程
cmd
(PID 42)启动 cmd
(PID 42)运行foo.bat
cmd
(PID 42)退出 Java喜欢知道该过程是否完成并检查PID 42
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.