如何从 Java 应用程序使用命令提示符命令

问题描述 投票:0回答:1

我正在尝试创建一个使用特定命令运行 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 个命令有关。

java cmd pipe
1个回答
0
投票

我想您可以使用条件执行,如链接或此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); }

runCMD() 方法:

/** * 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&lt;String&gt;) 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()'. } } }

Column.jar 应用程序:

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] + "\""); } }

© www.soinside.com 2019 - 2024. All rights reserved.