【问题标题】:Java calling Powershell script with function and not returning Write-Host to javaJava用函数调用Powershell脚本并且不将Write-Host返回给java
【发布时间】:2021-04-10 16:31:28
【问题描述】:

我正在使用 Java 调用 powershell 脚本。 powershell 脚本是用函数构建的,该函数会将值写入控制台。我需要在 java 中捕获这些值。 我的 poweshell 脚本如下

 $TokenCSV="M:\work\Powershell\TokenExtractedFromDB_Spec.csv"
$TokenXlPath="M:\work\Powershell\TokenListconverted.xlsx"
$Switch="Token"
Write-Host "Inside ConvertCSVtoEXL2 calling fuc  :"
$x=ConverToExlFile $TokenCSV $TokenXlPath $Switch

###Function
function ConverToExlFile
{
 Param ([string]$TokenCSV,
        [string]$TokenXlPath,
        [string]$Switch)
    Write-Output "Inside ConverToExlFile Function  :"| Out-Null

    
    for($row = 2;$row -lt 10;$row++)
    {
    Write-Output "Inside for loop :$row"| Out-Null
    }
    return
}

当通过 java 调用上面的代码时,我没有在 while 循环中获取值,如下所示。它只是在 powershell 脚本执行后完成。

 Process proc = runtime.exec("cmd.exe /c powershell.exe  M:\\work\\Powershell\\V2\\ConvertCSVtoEXL2.ps1");
        System.out.println("2...");
        InputStream is = proc.getInputStream();
        InputStreamReader isr = new InputStreamReader(is);
        BufferedReader reader = new BufferedReader(isr);
        String line;
        System.out.println("3");
       while ((line = reader.readLine()) != null)
       {
            System.out.println(line);
            //System.out.println(reader.readLine());
            System.out.println("4");
       }

如果有人能帮我解决这个问题,那就太好了。

【问题讨论】:

    标签: java powershell


    【解决方案1】:
    • 你不需要cmd.exe。可以直接运行powershell.exe。
    • 您的 PowerShell 脚本正在将输出发送到 Out-Null,因此显然不会将任何内容写入标准输出。
    • powershell.exe 接受 -File 参数,您可以使用该参数来运行脚本。
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    public class PrcBldTs {
    
        public static void main(String[] args) throws IOException, InterruptedException {
            ProcessBuilder pb = new ProcessBuilder("powershell.exe", "-File", "M:\\work\\Powershell\\V2\\ConvertCSVtoEXL2.ps1");
            Process p = pb.start();
            try (InputStreamReader isr = new InputStreamReader(p.getInputStream());
                 BufferedReader br = new BufferedReader(isr)) {
                String line = br.readLine();
                while (line != null) {
                    System.out.println(line);
                    line = br.readLine();
                }
            }
            int exitStatus = p.waitFor();
            System.out.println("exit status = " + exitStatus);
        }
    }
    

    请注意,您必须调用方法 waitFor() 以便您的 java 代码等到 PowerShell 脚本终止。

    请记住,ProcessBuilder 确实不模拟 Windows 命令提示符。在ProcessBuilder 构造函数中,您需要将传递的命令拆分为单词列表。

    当然,如果您只想打印 PowerShell 脚本输出,您可以简单地调用 ProcessBuilder 类的方法 redirectIO()。那么上面的代码就变成了:

    import java.io.IOException;
    
    public class PrcBldTs {
    
        public static void main(String[] args) throws IOException, InterruptedException {
            ProcessBuilder pb = new ProcessBuilder("powershell.exe", "-File", "M:\\work\\Powershell\\V2\\ConvertCSVtoEXL2.ps1");
            pb.inheritIO();
            Process p = pb.start();
            int exitStatus = p.waitFor();
            System.out.println("exit status = " + exitStatus);
        }
    }
    

    【讨论】:

      【解决方案2】:

      你可以在从proc获取输入流之前使用proc.waitFor();

      【讨论】:

      • waitFor() 等到进程终止/完成。如果该进程输出某些内容并且该内容大于其内部缓冲区,则调用waitFor() 而不读取InputStream 将只是死锁。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多