1

我们正在尝试通过 Java 调用 Powershell 脚本,但是当我们尝试读取该脚本的输出时它会挂起。它挂在“input.readLine()”上

这是我们尝试过的代码:

        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 程序在尝试调用 powershell 脚本时挂起, 但这些建议均不适合我们。

我们还尝试了不使用 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();
    }
4

1 回答 1

1

使用ProcessBuilder. 任何暗示少量 I/O 的进程都应该完全拒绝通过 运行Runtime.exec(),唉,它无法检测到这一点。甲骨文并没有将其标记为@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
于 2013-06-28T23:57:07.333 回答