How to execute a PowerShell command from JavaFX

随声附和 提交于 2020-05-28 10:36:57

问题


I have this Powershell command that I would like know how to execute from 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

I've read and tried several examples I found online and in forums. But I'm still stuck! This is the JavaFx method I'm using:

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();
    }

Executing the command directly in PowerShell produces the right results. A .txt file with content is created. Like this one (which is correct):

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

(Goal is to fetch the various results out of the .txt file content and display them on a UI).

But using the code in the above method creates an empty .txt file. I'm certainly doing something wrong, and would need some help to fix it.

Do you have any ideas? Your time and help is very much appreciated!

AveJoe

PS: I'm using a Windows 10 Pro machine.


回答1:


I believe you are actually asking several questions, including

  1. How to execute powershell command from java?
  2. How to read a file in java?
  3. How to display contents of a text file in JavaFX GUI?

I will answer the first question.
(Indeed, I believe a post should contain a single question.)

The ProcessBuilder constructor takes an array of String. Each word in your command becomes a single element in the array. Words are separated by one or more space characters.
Also you need to read the Process output and error output. I recommend creating two separate threads - one for output and another for error. And since you can easily write the Process output to a file, there is no need to use Out-File in your powershell command.

Here is a java program to execute the powershell command from your question.

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.
            }
        }
    }
}

The output of the powershell command is written to file stdout00.txt. The file contains the following...

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

I recommend you read the article When Runtime.exec() won't. It is very old and was written before class ProcessBuilder was part of the JDK but it also applies to ProcessBuilder and therefore, in my opinion, still relevant to the latest JDK version (12.0.1 at time of writing this).

Note that my environment is Windows 10 (64 bit) and Oracle JDK 12.0.1 (also 64 bit)



来源:https://stackoverflow.com/questions/56957671/how-to-execute-a-powershell-command-from-javafx

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!