如何从JavaFX执行PowerShell命令

时间:2019-07-09 17:18:14

标签: powershell javafx

我有这个Powershell命令,我想知道如何从Java / JavaFx执行:

powershell.exe Get-WMIObject Get-WMIObject Win32_SerialPort | Select-Object Name,DeviceID,Description,Caption, PNPDeviceID,Status | Out-File -FilePath C:\\path\\to\\file\\test.txt

我已阅读并尝试了一些在网上和论坛中找到的示例。但是我仍然被卡住!这是我正在使用的JavaFx方法:

public void PowerShellCommand() throws IOException
    {
        String command = "powershell.exe Get-WMIObject Get-WMIObject Win32_SerialPort | Select-Object Name,DeviceID,Description,Caption, PNPDeviceID,Status | Out-File -FilePath C:\\path\\to\\file\\test.txt";
        Process powerShellProcess = Runtime.getRuntime().exec(command);
        powerShellProcess.getOutputStream().close();
    }

直接在PowerShell中执行命令会产生正确的结果。 将创建一个包含内容的.txt文件。像这样(正确):

Name        : Kommunikationsanschluss (COM1)
Description : Kommunikationsanschluss
Caption     : Kommunikationsanschluss (COM1)
PNPDeviceID : ACPI\PNP0501\1
Status      : OK

目标是从.txt文件内容中提取各种结果,并将其显示在用户界面上)。

但是使用上述方法中的代码将创建一个空的.txt文件。我当然做错了,需要一些帮助来解决。

您有什么想法吗?非常感谢您的时间和帮助!

AveJoe

PS:我正在使用Windows 10 Pro计算机。

1 个答案:

答案 0 :(得分:3)

我相信您实际上是在问几个问题,包括

  1. 如何从Java执行powershell命令?
  2. 如何在Java中读取文件?
  3. 如何在JavaFX GUI中显示文本文件的内容?

我将回答第一个问题。
(实际上,我认为帖子中应该包含一个问题。)

ProcessBuilder构造函数采用String的数组。命令中的每个单词都将成为数组中的单个元素。单词由一个或多个空格字符分隔。
另外,您需要阅读Process输出和错误输出。我建议创建两个单独的线程-一个用于输出,另一个用于错误。而且,由于您可以轻松地将Process输出写入文件,因此无需在powershell命令中使用Out-File

这是一个Java程序,可以根据您的问题执行powershell命令。

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

public class ProcBldr {

    public static void main(String[] args) {
        ProcessBuilder procBldr = new ProcessBuilder("C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
                                                     "Get-WMIObject",
                                                     "Win32_SerialPort",
                                                     "|",
                                                     "Select-Object",
                                                     "Name,DeviceID,Description,Caption,PNPDeviceID,Status");
        Process proc;
        try {
            proc = procBldr.start(); //throws java.io.IOException
            Thread out = new Thread(new ProcOutput(proc.getInputStream(), new File("C:\\Users\\USER\\stdout00.txt")));
            Thread err = new Thread(new ProcOutput(proc.getErrorStream(), new File("C:\\Users\\USER\\stderr00.txt")));
            out.start();
            err.start();
            int exitCode = proc.waitFor(); //throws java.lang.InterruptedException
            out.join();
            err.join();
            System.out.println("\nExited with error code : " + exitCode);
        }
        catch (IOException | InterruptedException x) {
            x.printStackTrace();
        }
    }
}

class ProcOutput implements Runnable {
    private BufferedReader buffReader;
    private PrintWriter pw;

    public ProcOutput(InputStream is, File f) throws IOException {
        InputStreamReader isr = new InputStreamReader(is);
        buffReader = new BufferedReader(isr);
        pw = new PrintWriter(f);
    }

    public void run() {
        try {
            String line = buffReader.readLine();
            while (line != null) {
                pw.append(line);
                pw.append(System.lineSeparator());
                line = buffReader.readLine();
            }
        }
        catch (IOException xIo) {
            throw new RuntimeException(xIo);
        }
        finally {
            pw.close();
            try {
                buffReader.close();
            }
            catch (IOException xIo) {
                // Ignore.
            }
        }
    }
}

powershell命令的输出被写入文件stdout00.txt。该文件包含以下内容...

Name        : Communications Port? (COM1)
DeviceID    : COM1
Description : Communications Port
Caption     : Communications Port? (COM1)
PNPDeviceID : ACPI\PNP0501\0
Status      : OK

我建议您阅读文章When Runtime.exec() won't。它很老,是在类ProcessBuilder成为JDK的一部分之前编写的,但是它也适用于ProcessBuilder,因此,我认为仍然与最新的JDK版本(在本指南撰写之时为12.0.1)有关。写这个)。

请注意,我的环境是Windows 10(64位)和Oracle JDK 12.0.1(也是64位)