2013-01-03 55 views
2

我正在用NetBeans構建一個GUI,並且GUI中的一個按鈕需要使用PowerShell腳本。我試圖獲取腳本的輸出並將其放入GUI中的JTextArea中。這是我到目前爲止。我做了一些調試,似乎掛在while循環中,但我爲什麼這樣做是困惑的。嘗試調用powershell腳本時Java程序掛起

private void runButtonActionPerformed(java.awt.event.ActionEvent evt) {           
    try { 
     Runtime runtime = Runtime.getRuntime(); 
     Process proc = runtime.exec("cmd powershell C:/hello1.ps1"); 
     InputStream is = proc.getInputStream(); 
     InputStreamReader isr = new InputStreamReader(is); 
     BufferedReader reader = new BufferedReader(isr); 
     String line; 
     while ((line = reader.readLine()) != null) { 
      outputTextArea.setText(line); 
     } 
     reader.close(); 
     proc.getOutputStream().close(); 
    } catch (IOException ex) { 
     Logger.getLogger(BatchFrame.class.getName()).log(Level.SEVERE, null, ex); 
    } 
} 

這裏是一個簡單的powershell腳本,我試圖讓它使用它。

#Filename: hello1.ps1 
Write-Host "Hello World!" 
#End of Script 

我做了一些研究,我發現,這是掛了其他人,但只是因爲他們忘了關閉進程的輸出流。

+1

爲什麼要啓動命令處理器來啓動Powershell?此外,以非交互模式啓動Powershell可能更好(例如'powershell -NoLogo - 非交互式C:/ hello1.ps1') – ig0774

+1

我同意@ig0774的兩點。在混合中添加cmd只是浪費時間和資源,而混濁水域並沒有提供任何好處。 Powershell.exe獨立。 – alroc

+1

一旦我得到我的代碼工作,我會考慮這些建議。謝謝 – Franklin

回答

1
private void runButtonActionPerformed(java.awt.event.ActionEvent evt) {  
    String allOutput = "";         
    try { 
     Runtime runtime = Runtime.getRuntime(); 
     Process proc = runtime.exec("cmd /c powershell C:/hello1.ps1"); 
     BufferedReader errorReader = new BufferedReader(new InputStreamReader(proc.getErrorStream())); 
     BufferedReader outReader = new BufferedReader(new InputStreamReader(proc.getInputStream())); 
     String line; 
     while ((line = errorReader.readLine()) != null) { 
      allOutput += "\n" + line; 
     } 
     while ((line = outReader.readLine()) != null) { 
      allOutput += "\n" + line; 
     } 
     int retVal = proc.waitFor(); 
    } catch (IOException ex) { 
     Logger.getLogger(BatchFrame.class.getName()).log(Level.SEVERE, null, ex); 
    } 
    outputTextArea.setText(allOutput); 
} 
  • 適當地與CMD.EXE/C
  • 形成命令行檢查ErrorStream
  • 使用Process.waitFor()讀出的Java的文檔爲Process類。
  • 無需關閉的OutputStream,因爲你永遠不使用它,程序不應該指望用戶輸入(java的切換輸入和輸出的名稱是煩人)

注:上面的代碼是不因此可能會出現語法錯誤等。

+0

我修改了我的代碼,以考慮您的建議。但它仍然懸掛着。我在第一個while循環之前設置了一個斷點。它達到了這個突破點,但是當它碰到第一個聲明時它就會永遠掛起。無論如何,這對我來說沒有多大意義。如果我公然將錯誤放到我的powershell腳本中,它將進入第一個while循環並將輸出放入allOutput中,但一旦完成,它甚至不會觸及第二個循環,它只會掛起。 – Franklin

+0

我已經註釋了while循環和proce.waitFor()語句,並且它不再掛起,但是這樣就會破壞程序的整個目的。什麼可能導致這個?! – Franklin

+0

@Franklin - 在powershell腳本中,write-output而不是write-host是一個問題,或者只是字符串「Hello World!」。在自己的路線上。如果你真的需要它現在工作,沒有時間修補,那麼讓你的powershell腳本輸出結果到一個文件,然後在執行後讀取文件。 –

0

這是我的測試代碼,注意選擇「hack」或完成時關閉STDIN。

package test; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 

public class Test 
{ 
    private static boolean hack=false; 

    public static void main(String[] args) throws IOException 
    { 
     Runtime rt = Runtime.getRuntime(); 

     String cmd[]; 

     if (hack) 
      cmd=new String[]{"cmd","/c","C:\\WINDOWS\\system32\\WindowsPowerShell\\v1.0\\powershell.exe","-File","c:\\cygwin\\home\\jpyeron\\test.ps1", "<NUL"}; 
     else 
      cmd=new String[]{"C:\\WINDOWS\\system32\\WindowsPowerShell\\v1.0\\powershell.exe","-File","c:\\cygwin\\home\\jpyeron\\test.ps1"}; 

     final Process p = rt.exec(cmd); 

     Thread stdout = new Thread() 
     { 
      public void run() 
      { 
       InputStream out = p.getInputStream(); 
       BufferedReader in = new BufferedReader(new InputStreamReader(out)); 
       String line = null; 
       try 
       { 
        while ((line = in.readLine()) != null) 
        { 
         System.out.println(line); 
        } 
       } 
       catch (IOException e) 
       { 
        e.printStackTrace(); 
       }    
      }; 
     }; 
     stdout.start(); 

     Thread stderr = new Thread() 
     { 
      public void run() 
      { 
       InputStream err = p.getInputStream(); 
       BufferedReader in = new BufferedReader(new InputStreamReader(err)); 
       String line = null; 
       try 
       { 
        while ((line = in.readLine()) != null) 
        { 
         System.out.println(line); 
        } 
       } 
       catch (IOException e) 
       { 
        e.printStackTrace(); 
       }     
      }; 
     }; 
     stderr.start(); 

     if (hack) 
      ; 
     else 
      p.getOutputStream().close(); 
    } 
} 
1

我遇到了同樣的問題。我在while循環之前移動了proc.getOutputStream()。close(),並且一切正常。

0

這幫助了我:如果沒有錯誤,請不要讀取InputStream。 例如

private void takeAction() throws IOException, InterruptedException 
{ 
    String action = getAction(); // A powershell-Command 
    Process p = Runtime.getRuntime().exec (action); 

    InputStream is = p.getErrorStream(); 
    if (0 < is.available()) 
    { 
     BufferedReader br = new BufferedReader (
       new InputStreamReader (is)); 
     String err = br.readLine(); 
     while (null != err) 
     { 
      System.out.println ("takeAction() " + err); 
      err = br.readLine(); 
     } 
     p.getOutputStream().close(); 
    } 
} 
相關問題