通过Java运行cmd命令

82

我找到了几个通过Java类运行cmd命令的代码片段,但我无法理解它。

以下是用于打开cmd的代码

public void excCommand(String new_dir){
    Runtime rt = Runtime.getRuntime();
    try {
        rt.exec(new String[]{"cmd.exe","/c","start"});

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

我还找到了其他链接,可以添加其他命令,例如cd命令 http://www.coderanch.com/t/109753/Linux-UNIX/exec-command-cd-command-java

如何使用Java打开命令提示符并插入命令?

有人可以帮助我理解如何cd到一个目录吗,例如:

 cd C:\Program Files\Flowella

然后在该目录上运行其他命令?


这里有一些代码 - http://viralpatel.net/blogs/how-to-execute-command-prompt-command-view-output-java/ - Steam
15个回答

1
public class Demo {
    public static void main(String args[]) throws IOException {

        Process process = Runtime.getRuntime().exec("/Users/******/Library/Android/sdk/platform-tools/adb" + " shell dumpsys battery ");
        BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line = null;
        while (true) {
            line = in.readLine();
            if (line == null) { break; }
            System.out.println(line);
        }
    }
}

1
虽然这段代码可能解决了 OP 的问题,但强烈建议您提供有关为什么和/或如何回答问题的其他上下文。仅提供代码答案通常在长期内变得无用,因为未来遇到类似问题的观众无法理解解决方案背后的推理。 - E. Zeytinci

0

在Java中执行CMD的一种方式!

public void executeCmd() {
    String anyCommand="your command";
    try {
        Process process = Runtime.getRuntime().exec("cmd /c start cmd.exe /K " + anyCommand);

    } catch (IOException e) {
        e.printStackTrace();
    }
}

0

最简单和最短的方法是使用CmdTool库。

new Cmd()
         .configuring(new WorkDir("C:/Program Files/Flowella"))
         .command("cmd.exe", "/c", "start")
         .execute();

您可以在这里找到更多示例。


0

这里的价值在于使用&符号批处理命令以及正确的格式来使用cd更改驱动器。

public class CmdCommander {

public static void main(String[] args) throws Exception {
    //easyway to start native windows command prompt from Intellij

    /*
    Rules are:
    1.baseStart must be dual start
    2.first command must not have &.
    3.subsequent commands must be prepended with &
    4.drive change needs extra &
    5.use quotes at start and end of command batch
    */
    String startQuote = "\"";
    String endQuote = "\"";
    //String baseStart_not_taking_commands = " cmd  /K start ";
    String baseStart = " cmd  /K start cmd /K ";//dual start is must

    String first_command_chcp = " chcp 1251 ";
    String dirList = " &dir ";//& in front of commands after first command means enter
    //change drive....to yours
    String changeDir = " &cd &I: ";//extra & makes changing drive happen

    String javaLaunch = " &java ";//just another command
    String javaClass = " Encodes ";//parameter for java needs no &

    String javaCommand = javaLaunch + javaClass;
    //build batch command
    String totalCommand =
            baseStart +
                    startQuote +
                    first_command_chcp +
                    //javaCommand +
                    changeDir +
                    dirList +
                    endQuote;

    System.out.println(totalCommand);//prints into Intellij terminal
    runCmd(totalCommand);
    //Thread t = Thread.currentThread();
    //t.sleep(3000);
    System.out.println("loppu hep");//prints into Intellij terminal

}


public static void runCmd(String command) throws Exception {

    Runtime rt = Runtime.getRuntime();
    Process proc = rt.exec(command);


}

}


为什么要为同一引号字符定义两个变量? - JGFMK
另外FYI - CD可以通过向exec提供参数来完成 - 作为文件类型 - 即基本文件夹。 - JGFMK
好的。我只是想把这个清单澄清给自己,以免思考。命令可能有几页长,因此很容易立即看到引号的开始和结束位置,并且它们已经放置好了。CD在那里只是为了显示它可以在那里,因为在许多情况下都需要它。您可以先在一个目录中执行命令,然后移动到另一个目录并在其中执行其他命令,这将成为您的新用户目录。这是因为您需要考虑Windows DLL加载顺序,因此必须知道当前目录,即Java用户目录。 - Tonecops

0

(就像其他人说的那样) 对于简单的命令,你可以直接执行,例如:
Runtime.getRuntime().exec("cmd /c mkdir H:\\test\\BBB");
(cmd /c 可能是必需的)

然而,对于一些复杂的命令,你可能需要执行一个双重的 cmd.exe /c cmd.exe /c
否则(如果你只使用一个),cmd会被静默地丢弃
(或者如果你不使用/c或使用一些奇怪的/c cmd组合模式,cmd可能会冻结),
我不知道为什么。

((我是如何发现它的?-- 我无法让它工作并尝试了多次;有一次我意外地复制了cmd并运行了它,然后发现了这个问题。))

@eg::

import java.io.IOException;
import java.nio.charset.StandardCharsets;

public class T1 {

  static String convertStreamToString(java.io.InputStream is) {
    java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
    return s.hasNext() ? s.next() : "";
  }

  public static void main(String[] args) throws InterruptedException, IOException {

    Process process;

    System.out.println("---"); // creates a folder `BBB`
    Runtime.getRuntime().exec("cmd /c mkdir H:\\test\\BBB");

    // System.out.println("---");
    // idk how to do `cd`

    System.out.println("---"); // list file & folder in C:\
    process = Runtime.getRuntime().exec("cmd.exe /c dir C:\\");
    System.out.println(convertStreamToString(process.getInputStream()));

    System.out.println("---"); // echo
    process = Runtime.getRuntime().exec("cmd.exe /c echo \"Some Line\"");
    System.out.println(convertStreamToString(process.getInputStream()));

    // @atten: notice the double `cmd.exe /c cmd.exe /c ` 
    // -- idk why must double - otherwise this wont execute
    System.out.println("---"); // uses mysqldump to do something 
    process = Runtime.getRuntime().exec("cmd.exe /c cmd.exe /c \"C:\\Program Files\\MySQL\\MySQL Server 8.0\\bin\\mysqldump.exe\" -u root -pmysql db_drawandchat_01 > \"H:\\DrawAndChatApp_db\\DrawAndChat_20230503_0134_03326.sql\"");

  }

  // Output::
  //
  // ---
  // ---
  //  Volume in drive C has no label.
  //  Volume Serial Number is 2C83-063F
  // 
  //  Directory of C:\
  // 
  // 2019/06/29  11:56    <DIR>          Intel
  // 2022/04/18  06:07    <DIR>          log
  // 2019/12/07  17:14    <DIR>          PerfLogs
  // 2023/04/22  01:13    <DIR>          Program Files
  // 2023/04/08  21:27    <DIR>          Program Files (x86)
  // 2020/12/08  00:15    <DIR>          Untitled
  // 2021/04/23  04:57    <DIR>          Users
  // 2023/04/25  09:33    <DIR>          Windows
  //                0 File(s)              0 bytes
  //                8 Dir(s)   3,268,296,704 bytes free
  // 
  // ---
  // "Some Line"
  // 
  // ---

}


更新

根据我的经验

ProcessBuilder 使用 字符串数组作为参数 是更好的选择。

@注意:

  • 使用字符串数组作为参数,不要使用整个字符串,否则解析可能会出错。
    CreateProcess error=2,系统找不到指定的文件

  • 删除不必要的双引号(例如:在执行路径周围的引号)
    因为您正在使用数组,所以空格路径cmd问题已经被消除了//实际上并没有,见下面的更新->仍然使用[a double cmd.exe /c cmd.exe /c])。
    Java-ProcessBuilder命令参数带有空格和双引号失败

  • 该数组基于“exec&flag&arg&path”分隔
    --通常,在任何空格处分隔(尽管不在路径上)

    • 有时不分隔标志和参数(如果它们之间没有空格),例如:-pPASSWORD

@eg:: [将字符串命令转换为ProcessBuilder中的数组命令]

(以下代码在一些小修改后曾经工作过,但是没有测试

  public class T1 {

    public static void main(String[] args) throws InterruptedException, IOException {

      String cmdStr_loadFile = "cmd.exe /c cmd.exe /c "
                               + "\"C:\\Program Files\\MySQL\\MySQL Server 8.0\\bin\\mysql.exe\" "
                               + "-u root "
                               + "-pmysql "
                               + "--database db_drawandchat_02 "
                               + "< "
                               + "\"H:\\DrawAndChatApp_db\\DrawAndChat_test.sql\"";

      ArrayList<String> cmdArr_loadFile = new ArrayList<>(Arrays.asList("cmd", "/c",
          "C:\\Program Files\\MySQL\\MySQL Server 8.0\\bin\\mysql.exe",
          "-u", "root",
          "-pmysql",
          "--database", "db_drawandchat_02",
          "<",
          "H:\\DrawAndChatApp_db\\DrawAndChat_test.sql"));

      try {
        //      Process process = Runtime.getRuntime().exec(cmdStr_loadFile);

        ProcessBuilder processBuilder = new ProcessBuilder(cmdArr_loadFile);
        //      processBuilder.directory(new File("H:/"));
        processBuilder.redirectOutput(Redirect.INHERIT);
        processBuilder.redirectError(Redirect.INHERIT);
        //      processBuilder.redirectInput(Redirect.INHERIT);

        Process process = processBuilder.start();

        try {
          process.waitFor(20, TimeUnit.SECONDS);
          //        System.out.println(StringUtil.convertStreamToString(process.getInputStream()));
        } catch (InterruptedException e) {
          throw new Error(e);
        }
      } catch (IOException e) {
        throw new Error(e);
      }
    }

  }

更新

在使用 >"a double cmd.exe /c cmd.exe /c"
的情况下,使用 >"ProcessBuilder with array of String as args" 也是可行的。

特别是当你的路径中存在空格-- 可执行文件路径&&文件路径参数都包含空格时

@例如::

    ArrayList<String> cmdArr_saveFile = new ArrayList<>(
        Arrays.asList("cmd", "/c", "cmd", "/c",
                      "C:\\Program Files\\MySQL\\MySQL Server 8.0\\bin\\mysqldump.exe",
                      "-u", "root",
                      "-pmysql",
                      "db_drawandchat_01",
                      ">",
                      "H:\\DrawAndChatApp_db\\DrawAndChat test2.sql"));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接