3

NetBeans を使用して GUI を作成しています。GUI のボタンの 1 つで、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

私はいくつかの調査を行い、他の人がハングしていることに気付きましたが、それはプロセスの出力ストリームを閉じるのを忘れたからです。

4

4 に答える 4

3

私は同じ問題を抱えていました。while ループの前に proc.getOutputStream().close() を移動し、すべてが機能しました

于 2015-07-20T22:48:22.927 に答える
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 で適切に作成します。
  • エラーストリームを確認する
  • Process.waitFor() を使用して、Process クラスの Java ドキュメントを読みます。
  • OutputStream を使用することはなく、プログラムはユーザー入力を期待すべきではないため、OutputStream を閉じる必要はありません (Java で入力と出力の名前を切り替えるのは面倒です)。

上記のコードはテストされていないため、構文エラーなどが発生する可能性があることに注意してください。

于 2013-01-03T13:50:13.467 に答える
0

これが私のテスト済みコードです。完了したら「ハック」するか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();
    }
}
于 2015-04-15T00:59:39.320 に答える
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 ();
    }
}
于 2016-03-04T12:33:17.927 に答える