2012-01-05 132 views
6

我試圖運行一個Java應用程序,該應用程序在啓動時創建新的PowerShell進程,然後再與它進行多次交互。調用powershell.exe並讓它執行單個命令並返回輸出對我來說工作正常。如果我不想讓powershell進程立即完成/退出但保持打開狀態,則可以寫入其outputStream並從inputStream接收結果。與從Java應用程序調用的Powershell進程交互

  String input = "dir"; 

      String[] commandList = {"powershell.exe", "-Command", "dir"}; 

      ProcessBuilder pb = new ProcessBuilder(commandList); 

      Process p = pb.start(); 

      if(input != null) { 
       PrintWriter writer = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(p.getOutputStream())), true); 
       writer.println(input); 
       writer.flush(); 
       writer.close(); 

      } 

      //p.getOutputStream().close(); 

      Gobbler outGobbler = new Gobbler(p.getInputStream()); 
      Gobbler errGobbler = new Gobbler(p.getErrorStream()); 
      Thread outThread = new Thread(outGobbler); 
      Thread errThread = new Thread(errGobbler); 
      outThread.start(); 
      errThread.start(); 

      System.out.println("Waiting for the Gobbler threads to join..."); 

      outThread.join(); 
      errThread.join(); 

      System.out.println("Waiting for the process to exit...");                   

       int exitVal = p.waitFor(); 
       System.out.println("\n****************************"); 
       System.out.println("Command: " + "cmd.exe /c dir"); 
       System.out.println("Exit Value = " + exitVal); 
       List<String> output = outGobbler.getOuput(); 
       input = ""; 
       for(String o: output) { 
         input += o; 
       } 

      System.out.println("Final Output:"); 
      System.out.println(input); 

此代碼從powershell - 罰款返回「dir」命令的結果。但正如你所看到的,我試圖運行使用

   PrintWriter writer = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(p.getOutputStream())), true); 
       writer.println(input); 
       writer.flush(); 

這無論如何沒有效果了第二次「目錄」命令 - 當我運行我的代碼沒有第二DIR輸出顯示。我也有一個powershell.exe選項嘗試打開PowerShell的但不是立即關閉它:

String[] commandList = {"powershell.exe", "-NoExit", "-Command", "dir"}; 

但後來我的代碼掛起,這意味着gobbler之誰消耗的過程實例的InputStream不讀任何東西 - 很奇怪:他們甚至沒有讀第一行 - 至少必須有一些輸出....

我也試圖在寫第二個「dir」命令後關閉進程的outputStream - 沒有改變一切。

任何幫助,高度讚賞。 謝謝 Kurt

回答

0

這聽起來正確的是由另一個過程產生的過程的性質。我認爲你正在經歷非常標準的行爲。

這是關鍵的:p.waitFor()

從Java文檔:

導致當前線程如果需要等待,直到通過此處理對象表示的進程已經終止。

您將無法接收到PowerShell輸出流,直到它終止。當你與-NoExit一起運行時,它永遠不會退出,這就是爲什麼你會遇到這種情況。

如果您從Sysinternals運行ProcExp,您將能夠看到Java進程啓動一個PowerShell子進程。

所以我認爲你不能像它在內存中的活動對象那樣與它交互。

+0

謝謝安迪。然後在調用powershell.exe和cmd.exe之間必須有區別。因爲當我改變這個命令時:'String [] commandList = {「cmd.exe」,「/ k」,「dir」};'我實際上可以寫另一個「dir」命令到cmd.exe並獲得其反饋。所以在這種情況下,我保持cmd.exe運行(/ k開關),並可以發送後續命令。沒辦法,我可以用powershell.exe做同樣的事情嗎? – Kurt 2012-01-05 12:31:32

+0

@Kurt當你有cmd.exe運行第二個命令時,你是否再次用'pb.start()'運行它?如果是這樣,我認爲你可能會旋轉另一個cmd.exe。爲了確保使用ProcExp觀察過程樹,以更好地瞭解幕後發生的事情。 – 2012-01-05 13:07:02

+0

不,我使用完全相同的代碼 - 沒有第二次調用pb.start()。當我運行代碼時,我可以看到一個cmd.exe和一個conhost.exe打開 - 不是兩個。在輸出中,您還可以看到我的第二個「dir」命令被輸入到打開的cmd中。exe: – Kurt 2012-01-05 13:23:16

相關問題