2012-07-16 82 views
4

這應該很簡單,但我在JavaDocs中看不到任何有用的東西。如何監視ProcessBuilder運行的外部進程?

我需要的是從我的Java代碼運行一些外部進程,然後能夠監視此進程是否已關閉。換句話說,我希望能夠可靠地確定我的外部流程是否未被用戶結束。

如果不存在跨平臺解決方案,我會接受在Linux下工作的任何東西。

我的代碼當前片段:

public static void main(String[] args) { 
    ProcessBuilder pb = new ProcessBuilder("some proces name"); 

    try { 
     Process p = pb.start(); 
     // p.isRunning(); <- now, that would be helpful :-) 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 
+0

你是什麼意思「關機」與「未由用戶結束」。你在談論錯誤代碼還是其他一些輸出? – Gray 2012-07-16 18:37:24

+0

那麼,說「由用戶結束」可能確實沒那麼準確。我真正想知道的是,如果這個過程仍然在任何時候運行。 – 2012-07-16 18:45:41

回答

7

啓動一個新線程它要求Process.waitFor()並設置一個標誌時調用返回。那麼,只要您想查看過程是否已完成,您就可以檢查該標誌。

public class ProcMon implements Runnable { 

    private final Process _proc; 
    private volatile boolean _complete; 

    public boolean isComplete() { return _complete; } 

    public void run() { 
    _proc.waitFor(); 
    _complete = true; 
    } 

    public static ProcMon create(Process proc) { 
    ProcMon procMon = new ProcMon(proc); 
    Thread t = new Thread(procMon); 
    t.start(); 
    return procMon; 
    } 
} 

(省略了一些樣板)。

5

我不知道我理解的問題,但要做到這一點的一種方法是調用process.exitValue();。它拋出一個異常,如果進程尚未終止:

/** 
* Returns the exit value for the subprocess. 
* 
* @return the exit value of the subprocess represented by this 
*   <code>Process</code> object. by convention, the value 
*   <code>0</code> indicates normal termination. 
* @exception IllegalThreadStateException if the subprocess represented 
*    by this <code>Process</code> object has not yet terminated. 
*/ 
abstract public int exitValue(); 

如果你不介意一個黑客,你可以這樣做,如果你是它使用UNIXProcess類〜Unix系統的工作如下。這確實然而使用反射:

ProcessBuilder pb = new ProcessBuilder("/bin/sleep", "5"); 
Process process = pb.start(); 
// open accessability of the UNIXProcess.hasExited field using reflection 
Field field = process.getClass().getDeclaredField("hasExited"); 
field.setAccessible(true); 
// now we can get the field using reflection 
while (!(Boolean) field.get(process)) { 
    ... 
} 
+0

想過它,但這聽起來有點像API'濫用'。我想知道過程是否正在運行,而不是過程終止沒有發生。我知道它應該是相同的,但老實說,我期待一些API組件,它將採用現有的'Process'實例,並且可以提供有關在該進程中運行的線程狀態的一些額外的元數據。 – 2012-07-16 18:49:33

+0

@ŁukaszBachman我不會認爲這是API「濫用」。全部是非布爾條件。我還添加了一種方法來獲得'hasExited'內部值,但它是一種使用反射的黑客。 – Gray 2012-07-16 18:51:00

+0

我會用'waitFor()',但是+1反思想法。 – 2012-07-16 18:57:42