首页 > 解决方案 > 如何从 JavaFX 执行 PowerShell 命令

问题描述

我有这个 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 文件内容中提取各种结果并将它们显示在 UI 上)。

但是使用上述方法中的代码会创建一个空的 .txt 文件。我肯定做错了什么,需要一些帮助来解决它。

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

阿维乔

PS:我使用的是 Windows 10 Pro 机器。

标签: powershelljavafx

解决方案


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

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

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

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

这是一个 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 位)


推荐阅读