我正在尝试创建一个使用特定命令运行 CMD 的 java 程序
dir C:\windows | java -jar C:\\Column.jar 3
当我手动运行它时,但我无法从java运行它。
我已经阅读并尝试了我所看到的每一篇文章,但没有运气。到目前为止我的代码如下所示:
public class Test {
public static void main(String[] args) throws IOException, InterruptedException {
String comand = "cmd /c start dir \"C:\\Windows\" | java -jar C:\\Column.jar 3";
Process process = Runtime.getRuntime().exec(comand);
process.waitFor();
}
}
PS:“Column.jar X”仅保留字符串的 X 列(或使用制表符空格作为分隔符的子字符串)。
PS2:我认为这与管道有关,或者至少与同时使用 2 个命令有关。
我想您可以使用条件执行,如链接或此StackExchange Post中所述。
我个人会单独运行这两个命令,但是我不太确定总体任务可能是什么。
如果您想从命令解释器窗口 (CMD) 中执行多个命令,则如下所示:
直接在CMD窗口中执行多个命令:
cmd /C dir "C:\Windows" && java -jar "C:\Column.jar" "3"
当然前提是,
Column.jar
文件位于驱动器C
的根目录中。但是,如果您尝试在 Java 中使用 Process.exec() 或 ProcessBuilder 运行它,您可能不会那么幸运......至少我不是。当尝试打开命令解释器 (CMD) 窗口并运行这两个命令时,第一个进程(命令)似乎永远不会终止。我确定我只是缺少某种流程设置。
批处理文件中的多个命令:
有效的方法是从一个小批处理文件中运行命令。为了便于讨论,我们将其命名为
RunBatch.bat
。只需一行即可打开 CMD 窗口并运行这两个命令:
@ECHO OFF
作为第一行,然后按ENTER键;cmd /C dir "C:\Windows" && java -jar "C:\Column.jar" "3"
。再次假设 Windows 位于驱动器 C
上且 Column.jar
位于
驱动器根目录C
;RunBatch.bat
在已知位置(让我们
使用驱动器的根目录C
)。当然,您可以使用代码创建此批处理文件,但您需要知道,如果 Windows 安装在该驱动器上,则在驱动器
C
的根目录中创建它不是一个好主意。这样做需要特殊权限,并且很可能会出现“访问被拒绝!”消息。也许最好将其放置在 C:\\Users\\Public\\
或具有 保证访问权限的更好位置。只需记住它在哪里,因为您需要知道该批处理文件的完整路径。 您还会注意到,正在启动的
Column.jar
文件接受两个命令行参数,其中第一个是要从中获取单词的字符串。第二个参数是要在控制台窗口中获取和显示的文字字数。如果未提供命令行参数,则使用默认值。默认字符串是:
"This is a demo test String!"
,默认列(要获取的单词)是1
。要创建并运行此批处理文件,您可以使用类似以下内容:
// Create batch file:
String stringArgForJAR = "My dog ran up the slippery slope and slid back down!";
int desiredWordNumberArgForJAR = 6;
String cmdCommands = "cmd /C dir \"C:\\Windows\" && java -jar \"C:\\Column.jar\" "
+ "\"" + stringArgForJAR + "\" \"" + desiredWordNumberArgForJAR + "\"";
String batchFilePath = "C:\\Users\\Public\\RunBatch.bat";
try (java.io.PrintWriter writer = new java.io.PrintWriter(batchFilePath)) {
writer.println("@ECHO OFF:);
writer.print(cmdCommands);
writer.flush();
}
catch (FileNotFoundException ex) {
System.out.println(ex.getMessage());
}
// Run the created batch file....
Process process = null;
try {
String[] command = {"cmd.exe", "/C", "Start", batchFilePath};
process = Runtime.getRuntime().exec(command);
process.waitFor();
}
catch (IOException | InterruptedException ex) {
ex.printStackTrace();
}
finally {
if (process != null && process.isAlive()) {
process.destroy();
}
}
到目前为止,我假设您希望在命令解释器窗口中显示所有内容,至少这是我从您的帖子中得到的笑话。如果您实际上应该将每个运行进程的响应放置在列表接口或字符串(列表)中并且根本看不到命令解释器窗口,那么您可能需要使用这样的东西:
所有运行进程响应都在一个列表中:
String directoryToList = "C:\\Windows";
String stringArgForJAR = "My dog ran up the slippery slope and slid back down!";
int desiredWordNumberArgForJAR = 6;
String command = "dir \"" + directoryToList + "\" && java -jar \""
+ "C:\\Column.jar\" \""
+ stringArgForJAR + "\" \"" +desiredWordNumberArgForJAR + "\"";
List<String> responses = runCMD(command);
// Display contents of List in Console Window:
System.out.println("All Responses:\n==============\n");
for (String strg : responses ) {
System.out.println(strg);
}
System.out.println();
在单独的列表中处理响应:
String directoryToList = "C:\\Windows";
String stringArgForJAR = "My dog ran up the slippery slope and slid back down!";
int desiredWordNumberArgForJAR = 6;
String command1 = "dir \"" + directoryToList + "\"";
List<String> windowsDir = runCMD(command1);
System.out.println("Windows Directory:\n==================");
// Run Column.jar:
String command2 = "java -jar C:/Users/Devil/NetBeansProjects/Column/dist/Column.jar \""
+ stringArgForJAR + "\" \"" + desiredWordNumberArgForJAR + "\"";
System.out.println("Desired Word from String:\n=========================");
List<String> jarResponse = runCMD(command2);
// Display contents of List for command1 in Console Window:
for (String strg : windowsDir) {
System.out.println(strg);
}
System.out.println();
// Display contents of List for command2 in Console Window:
for (String strg : jarResponse) {
System.out.println(strg);
}
/**
* This method is specifically designed solely for running the Microsoft
* Windows CMD command prompt and having the results that would normally be
* displayed within a Command Prompt Window placed into a string ArrayList
* (List) instead.<br><br>
* <p>
* <b>Example Usage:</b><pre>
* {@code
* List<String> response = runCMD("dir \"C:/Windows\"");
* // Display the List:
* for (String str : response) {
* System.out.println(str);
* }
* }</pre>
*
* @param commandString (String) The command string to pass to the Command
* Prompt. You do not need to place "cmd" within your
* command string because it is applied automatically.
* As a matter of fact if you do it is automatically
* removed.<br>
*
* @return (List<String>) A string ArrayList containing the results of
* the processed command.
*/
public static java.util.List<String> runCMD(String commandString) {
if (commandString.toLowerCase().startsWith("cmd ")) {
commandString = commandString.substring(4);
}
java.util.List<String> result = new java.util.ArrayList<>();
Process p = null;
try {
p = Runtime.getRuntime().exec("cmd /C " + commandString);
try (java.io.BufferedReader in = new java.io.BufferedReader(
new java.io.InputStreamReader(p.getInputStream()))) {
String line;
while ((line = in.readLine()) != null) {
result.add(line);
}
}
p.waitFor();
return result;
}
catch (java.io.IOException | InterruptedException ex) {
javax.swing.JOptionPane.showMessageDialog(null, "<html>IO Error during processing of RunCMD()!"
+ "<br><br>" + ex.getMessage() + "</html>",
"runCMD() Method Error", javax.swing.JOptionPane.WARNING_MESSAGE);
return null;
}
finally {
if (p != null && p.isAlive()) {
p.destroy(); // Kill the Process in case of abnormal process termination through 'waitFor()'.
}
}
}
public class Column {
public static void main(String[] args) {
// The default string to get a word from:
String defaultString = "This is a demo test String!";
// Get the number of words within the default string:
int numberOfWords = defaultString.split("\\s+").length;
// Default column number:
int defaultColomn = 1;
System.out.println();
// Check for a command-line argument:
// Has Command-Line arguments been supplied? This app will accept 2 arguments
if (args.length > 0) {
// Yes...
/* Is there a a second command-line argument? If so, we
want to process this first because we need to get a
new number of words count for conditions when checking
validity of the first supply argument (Word number). */
if (args.length >= 1) {
// If the supplied argument is empty - ignore it and use default!
if (!args[0].trim().isEmpty()) {
// Desired string to process validation has passed!
defaultString = args[0];
// Update the numberOfWords variable based on non-default string:
numberOfWords = defaultString.split("\\s+").length;
}
}
if (args.length == 2) {
// Validate the passed command-line argument:
if (!args[1].matches("\\d+") || Integer.parseInt(args[1]) < 1
|| Integer.parseInt(args[1]) > numberOfWords) {
System.out.println("Invalid Command-Line Argument (Argument: -> " + args[1] + ")! Either the");
System.out.println("supplied argument is not a valid number or the number is");
System.out.println("Out Of Bounds! - Only values of 1 to " + numberOfWords + " are permitted!");
System.out.println();
return;
}
// Desired word number Validation passed!
defaultColomn = Integer.parseInt(args[1]);
}
}
// No... Use default column number (1):
System.out.println("String: -> \"" + defaultString + "\"");
String[] words = defaultString.trim().replaceAll("\\p{Punct}", "").split("\\s+");
System.out.println("The word in literal column " + defaultColomn
+ " is -> \"" + words[defaultColomn - 1] + "\"");
}
}