powershell - 如何从 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 机器。
解决方案
我相信您实际上是在问几个问题,包括
- 如何从java执行powershell命令?
- 如何在java中读取文件?
- 如何在 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 位)