Java程序在试图调用powershell脚本时挂起



我正在用NetBeans构建GUI, GUI中的一个按钮需要使用powershell脚本。我试图获得脚本的输出并将其放入GUI中的JTextArea。这是我目前所知道的。我做了一些调试,它似乎在while循环中挂起,但我很困惑为什么它会这样做。

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

我做了一些研究,我注意到它是挂在其他人,但只是因为他们忘记关闭进程输出流。

我也有同样的问题。我把proc.getOutputStream().close()移到while循环之前,一切都工作了

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()读取Process类的java文档。
  • 不需要关闭OutputStream,因为你从不使用它,程序不应该期望用户输入(java切换输入和输出的名称是烦人的)

注意上面的代码没有经过测试,所以可能会有语法错误等等。

这是我测试的代码,注意选择"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();
    }
}

这对我很有帮助:如果没有错误,不要读取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 ();
    }
}

相关内容

  • 没有找到相关文章

最新更新