2013-06-28 165 views
1

我們試圖通過Java調用Powershell腳本,但是當我們嘗試讀取該腳本的輸出時,它會掛起。它掛在「input.readLine()」java input.readLine在啓動powershell腳本後掛起

這是我們已經嘗試了代碼:

 String command = "cmd /c powershell C:\\_checkouts\\TestPowerShell\\passwordExpirationTime.ps1"; 
     Process p = Runtime.getRuntime().exec(command); 
     new InputStreamReader(p.getInputStream()); 

     BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream())); 

     StringBuilder stringBuilder = new StringBuilder();; 
     for (String line = input.readLine(); line != null; line = input.readLine()) { 
      stringBuilder.append(line); 
     } 

     input.close(); 

     String msg = stringBuilder.toString(); 

     System.out.println("msg: " + msg); 

我們試圖尋找這個解決方案Java program hangs when trying to invoke powershell script 但沒有這些建議爲我們工作。

我們也試過沒有cmd/c和cmd/k。我們真的希望這是一個可以調用任何腳本的泛型類。即BAT,BASH,SH,Powershell等。

任何想法?

得益於以下這裏的答案是,工作代碼:

try{ 
     final ProcessBuilder pb = new ProcessBuilder("powershell","C:\\psFile.ps1"); 
     pb.redirectInput(Redirect.from(new File("NUL"))); 
     final Process p = pb.start(); 
     final int retcode = p.waitFor(); 

     InputStream is = p.getInputStream(); 
     InputStreamReader isr = new InputStreamReader(is); 
     BufferedReader br = new BufferedReader(isr); 
     String line; 

     while ((line = br.readLine()) != null) { 
      System.out.println(line); 
     } 
     br.close(); 
    }catch (Exception e){ 
     e.printStackTrace(); 
    } 

這裏有一些額外的信息。我們的powershell因爲受到限制而返回錯誤。這就是爲什麼我們需要將所有重定向到NUL。一旦我們固定的,它並沒有返回一個錯誤,我們能夠簡化我們的代碼是:

try{ 
     final ProcessBuilder pb; 

     pb = new ProcessBuilder(args); 

     final Process p = pb.start(); 

     InputStream is = p.getInputStream(); 
     InputStreamReader isr = new InputStreamReader(is); 
     BufferedReader br = new BufferedReader(isr); 
     String line; 

     while ((line = br.readLine()) != null) { 
      System.out.println(line); 
     } 
     br.close(); 
    }catch (Exception e){ 
     e.printStackTrace(); 
    } 

回答

1

使用ProcessBuilder。暗示一點I/O的任何進程都應該徹底拒絕通過Runtime.exec()運行,唉,它無法檢測到。而Oracle並沒有將其標記爲@Deprecated,這很遺憾。

總之:

final File logFile = new File("/path/to/logfile"); 
final ProcessBuilder pb = new ProcessBuilder("powershell", "/path/to/the/ps1"); 
pb.redirectOutput(Redirect.to(logFile)); 
pb.redirectErrorStream(true); 

final Process p = pb.start(); 
final int retcode = p.waitFor(); 

// deal with retcode 
// read result from the log file 
+0

我試圖做到這一點,但它掛在p.waitFor();如果我發表評論,並等待或暫停調試器,然後繼續它將工作。但是如果我使用waitFor(),就好像這個過程永遠不會結束,所以它不會繼續。 – user2533615

+0

嘗試並添加'pb.redirectInput(Redirect.from(新文件(「NUL」))' – fge

+0

好吧,它工作!它看起來需要發送輸入的地方是否有任何問題在Linux和OSX上使用這個跨平臺?關於如何創建它的任何想法,所以它不需要寫入臨時文件夾,但可以全部在內存中完成? – user2533615