如何使用 Java 中执行 Windows 的 CMD 命令
在 CMD 中执行 BAT 脚本对用户不友好,而且有安全隐患,因此笔者编写了一些可以在 Java 中执行 Windows 的 CMD 命令的 API。
核心代码
package org.wangpai.demo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.stream.Collectors;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.experimental.Accessors;
@Accessors(chain = true)
public class WinCmd {
private Charset cmdCharset;
@Getter(AccessLevel.PROTECTED)
private Process process;
private String originalCommandMsg;
private String output;
private int exitValue;
private WinCmd() {
super();
}
public static WinCmd getInstance() {
return new WinCmd();
}
public int getExitValue() throws Exception {
if (this.process == null) {
throw new Exception("需要先执行命令后才能获取退出码");
}
this.exitValue = process.waitFor();
return this.exitValue;
}
public String getOutput() throws Exception {
if (this.process == null) {
throw new Exception("需要先执行命令后才能获取输出");
}
if (this.output != null) {
return this.output;
}
var inputStream = process.getInputStream();
this.cmdCharset = Charset.forName((String) System.getProperties().get("sun.jnu.encoding"));
var lines = new BufferedReader(new InputStreamReader(
inputStream, this.cmdCharset)).lines();
this.output = lines.collect(Collectors.joining(System.lineSeparator()));
return this.output;
}
public String getCommand() throws Exception {
if (this.originalCommandMsg == null) {
throw new Exception("还没有输入命令");
}
return this.originalCommandMsg;
}
public WinCmd execute(String command) throws Exception {
return this.exec(command);
}
private WinCmd exec(String originalCommand) throws IOException {
this.output = null;
this.originalCommandMsg = originalCommand;
this.process = Runtime.getRuntime().exec(this.originalCommandMsg);
return this;
}
}
package org.wangpai.demo;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class WinBat {
private int commandNum;
private Charset cmdCharset;
private String[] originalCommandMsg;
private Process[] processArray;
private String[] outputs;
private int[] exitValues;
private WinBat() {
super();
}
public static WinBat getInstance() {
return new WinBat();
}
public String getIntegrationOutput() throws Exception {
if (this.processArray == null) {
throw new Exception("需要先执行命令后才能获取输出");
}
if (this.outputs == null) {
this.cmdCharset = Charset.forName((String) System.getProperties().get("sun.jnu.encoding"));
this.outputs = new String[this.commandNum];
InputStream inputStream;
for (int index = 0; index < this.commandNum; ++index) {
inputStream = this.processArray[index].getInputStream();
var linesOutput = new BufferedReader(new InputStreamReader(
inputStream, this.cmdCharset)).lines();
this.outputs[index] = linesOutput.collect(Collectors.joining(System.lineSeparator()));
}
}
var stream = Stream.of(this.outputs);
return stream.collect(Collectors.joining(System.lineSeparator() + System.lineSeparator()));
}
public String getIntegrationCommand() throws Exception {
if (this.originalCommandMsg == null) {
throw new Exception("还没有输入命令");
}
var stream = Stream.of(this.originalCommandMsg);
return stream.collect(Collectors.joining(System.lineSeparator()));
}
public String[] getOriginalCommand() throws Exception {
if (this.originalCommandMsg == null) {
throw new Exception("还没有输入命令");
}
return this.originalCommandMsg;
}
public int[] getExitValues() throws Exception {
if (this.processArray == null) {
throw new Exception("需要先执行命令后才能获取退出码");
}
this.exitValues = new int[this.commandNum];
for (int index = 0; index < this.commandNum; ++index) {
this.exitValues[index] = this.processArray[index].waitFor();
}
return this.exitValues;
}
public int getLastExitValues() throws Exception {
if (this.processArray == null) {
throw new Exception("需要先执行命令后才能获取退出码");
}
var exitValues = this.getExitValues();
return exitValues[this.commandNum - 1];
}
private WinBat exec(String[] originalCommand) throws Exception {
this.outputs = null;
this.originalCommandMsg = originalCommand;
this.commandNum = originalCommand.length;
this.processArray = new Process[this.commandNum];
for (int index = 0; index < this.commandNum; ++index) {
this.processArray[index] = WinCmd.getInstance()
.execute(this.originalCommandMsg[index]).getProcess();
}
return this;
}
public WinBat execute(String[] command) throws Exception {
return this.exec(command);
}
}
完整代码
已上传至 GitCode 中,可免费下载:https://gitcode.net/wangpaiblog/20220110-win_cmd