Runtime.getRuntime.exex("abc.exe -parameters");
使用.waitFor()
无助于确定流程的完成情况。
答案 0 :(得分:17)
看起来JDK8引入了Process.isAlive()
。感到惊讶花了这么久......
与此同时,最佳选择似乎是轮询Process.exitValue()
,包含在try-catch中:
// somewhere previous...
String[] cmd = { "abc.exe", "-p1", "-p2" };
Process process = Runtime.getRuntime.exec(cmd);
// call this method repeatedly until it returns true
private boolean processIsTerminated () {
try {
process.exitValue();
} catch (IllegalThreadStateException itse) {
return false;
}
return true;
}
或者,类似的方法可以在进程终止时返回退出值,如果没有则返回其他指定值。
答案 1 :(得分:9)
Process.waitFor()
(javadoc)应工作。如果它不起作用,那么:
JVM或操作系统中存在一个错误(极不可能出现类似的错误)或
关于流程和/或您的Java代码,这意味着流程不会退出。
在当前版本的Java中,您还可以使用Process.isAlive
(javadoc)来测试进程状态,直到完成为止。对于Java 7及更早版本,有一个hacky解决方案需要轮询进程返回代码并捕获异常,但这是低效的。您应该尽快升级到Java 8或更高版本!
任务完成后,无限期等待。 (我不知道为什么)。
如果发生这种情况,那么waitFor()
或isAlive()
都无济于事。
从Java启动的进程不会/不能退出的最可能原因是:
阻止进程等待Java应用程序给它一些输入(通过其stdin),
阻止进程等待Java应用程序读取其输出(即其stdout或stderr),
等待某些外部事件被阻止;例如如果它试图说话没有响应的远程服务器,
某些东西发送了某种停止信号,或者
只是花了 looong 时间来运行。
这两个原因/原因中的前两个可以通过(分别)关闭连接到其标准输入的Java输出流,以及读取(并可能丢弃)连接到其标准输出和标准错误的Java输入流来解决。其他原因是棘手的,你唯一的选择就是“等待它”或者试图杀掉这个过程。
底线 - 您需要找出您的流程未完成的原因。被阻止的Process.waitFor()
呼叫是一种症状,而不是疾病。
答案 2 :(得分:1)
我有类似的问题,这里写的方法都不适合我。这是我的代码:
public void startCCleaner() {
System.out.println("Starting ccleaner...");
try {
Process process = new ProcessBuilder("C:\\Program Files\\CCleaner\\CCleaner64.exe").start();
if(process.waitFor() == 0 ){
System.out.println("Process terminated ");
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
答案 3 :(得分:-1)
如果你不想使用waitFor()
,显然你没有,你可以直接测试退出值。
import java.util.*;
import java.io.*;
public class ProcExitTest
{
public static void main(String args[])
{
try
{
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("<....>");
int exitVal = proc.exitValue();
System.out.println("Process exitValue: " + exitVal);
}
catch (InterruptedException ie)
{
ie.printStackTrace();
}
}
}
退出代码0表示正常终止。