【问题标题】:Run cmd commands through Java通过 Java 运行 cmd 命令
【发布时间】:2021-05-18 08:32:23
【问题描述】:

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

这是打开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

How to open the command prompt and insert commands using Java?

谁能帮我理解如何 cd 一个目录,例如:

 cd C:\Program Files\Flowella

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

【问题讨论】:

标签: java cmd cd


【解决方案1】:

从不同目录运行进程到 Java 程序的工作目录的一种方法是更改​​目录,然后在同一命令行中运行进程。您可以通过让cmd.exe 运行诸如cd some_directory && some_program 之类的命令行来做到这一点。

以下示例更改为不同的目录并从那里运行dir。诚然,我可以只 dir 那个目录而不需要 cd 到它,但这只是一个例子:

import java.io.*;

public class CmdTest {
    public static void main(String[] args) throws Exception {
        ProcessBuilder builder = new ProcessBuilder(
            "cmd.exe", "/c", "cd \"C:\\Program Files\\Microsoft SQL Server\" && dir");
        builder.redirectErrorStream(true);
        Process p = builder.start();
        BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String line;
        while (true) {
            line = r.readLine();
            if (line == null) { break; }
            System.out.println(line);
        }
    }
}

还要注意,我使用ProcessBuilder 来运行命令。除此之外,这允许我通过调用redirectErrorStream(true) 将进程的标准错误重定向到其标准输出。这样做只会让我读取一个流。

这在我的机器上给了我以下输出:

C:\Users\Luke\StackOverflow>java CmdTest
 Volume in drive C is Windows7
 Volume Serial Number is D8F0-C934

 Directory of C:\Program Files\Microsoft SQL Server

29/07/2011  11:03    <DIR>          .
29/07/2011  11:03    <DIR>          ..
21/01/2011  20:37    <DIR>          100
21/01/2011  20:35    <DIR>          80
21/01/2011  20:35    <DIR>          90
21/01/2011  20:39    <DIR>          MSSQL10_50.SQLEXPRESS
               0 File(s)              0 bytes
               6 Dir(s)  209,496,424,448 bytes free

【讨论】:

  • 非常感谢......或外部命令,虽然它适用于 cmd 并且我添加了环境变量的路径。
  • 这听起来像是PATH 问题。尝试打印出 PATH 环境变量的值,看看它是否包含您提到的 Android 命令的路径。 (使用System.getenv("PATH") 来获取它的值。)你没有说你是如何运行你的Java代码的(从命令提示符,从IDE,在Web应用程序中,......),所以我不能说你可以做些什么来解决这个明显的PATH 问题。
  • @LukeWoodward - 谢谢。您能解释一下这些字符串参数的含义 - "/c" 和 "cd \"C:\\Program Files\\Microsoft SQL Server\" && dir" 吗?我实际上是在尝试从 C:\Windows\system32 执行一个 svn 命令svn log --limit 1 http://svn.repo1.com/trunk/app。请帮我解决这个问题。
  • 我碰了运气,发现了怎么做 - ProcessBuilder builder = new ProcessBuilder("cmd.exe", "/c", my_svn_code); 它有效,但我不知道它是如何运作的。
  • @Steam: cmd.exe 是命令提示符。 /c 告诉命令提示符运行该行的其余部分,然后退出。使用命令提示符允许我更改目录 - cd 内置在命令提示符中,没有 cd.exe - 还可以使用 &amp;&amp; 将两个命令链接在一起。
【解决方案2】:

你可以试试这个:-

Process p = Runtime.getRuntime().exec(command);

【讨论】:

  • 可能是因为您使用的是Runtime.getRuntime().exec(...) 而不是ProcessBuilder?就个人而言,我认为 Runtime.getRuntime().exec(...) 已弃用。 (不过,投反对票的不是我。)
  • 我不是反对者,但是——您的代码与 OP 已有的代码几乎完全相同。它不会解决 OP 当前遇到的任何问题。
【解决方案3】:

如果您想执行cd 之类的操作,请使用:

String[] command = {command_to_be_executed, arg1, arg2};
ProcessBuilder builder = new ProcessBuilder(command);
builder = builder.directory(new File("directory_location"));

例子:

String[] command = {"ls", "-al"};
ProcessBuilder builder = new ProcessBuilder(command);
builder = builder.directory(new File("/ngs/app/abc"));
Process p = builder.start();

将命令和所有参数拆分为字符串数组的单独字符串很重要(否则ProcessBuilder API 将无法正确提供它们)。

【讨论】:

    【解决方案4】:

    这里有一个更完整的命令行执行实现。

    用法

    executeCommand("ls");
    

    输出:

    12/27/2017 11:18:11:732: ls
    12/27/2017 11:18:11:820: build.gradle
    12/27/2017 11:18:11:820: gradle
    12/27/2017 11:18:11:820: gradlew
    12/27/2017 11:18:11:820: gradlew.bat
    12/27/2017 11:18:11:820: out
    12/27/2017 11:18:11:820: settings.gradle
    12/27/2017 11:18:11:820: src
    

    代码

    private void executeCommand(String command) {
        try {
            log(command);
            Process process = Runtime.getRuntime().exec(command);
            logOutput(process.getInputStream(), "");
            logOutput(process.getErrorStream(), "Error: ");
            process.waitFor();
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
    
    private void logOutput(InputStream inputStream, String prefix) {
        new Thread(() -> {
            Scanner scanner = new Scanner(inputStream, "UTF-8");
            while (scanner.hasNextLine()) {
                synchronized (this) {
                    log(prefix + scanner.nextLine());
                }
            }
            scanner.close();
        }).start();
    }
    
    private static SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss:SSS");
    
    private synchronized void log(String message) {
        System.out.println(format.format(new Date()) + ": " + message);
    }
    

    【讨论】:

      【解决方案5】:

      我的例子(来自真实项目)

      文件夹——文件。

      zipFile, filesString — 字符串;

              final String command = "/bin/tar -xvf " + zipFile + " " + filesString;
              logger.info("Start unzipping: {}    into the folder {}", command, folder.getPath());
              final Runtime r = Runtime.getRuntime();
              final Process p = r.exec(command, null, folder);
              final int returnCode = p.waitFor();
      
              if (logger.isWarnEnabled()) {
                  final BufferedReader is = new BufferedReader(new InputStreamReader(p.getInputStream()));
                  String line;
                  while ((line = is.readLine()) != null) {
                      logger.warn(line);
                  }
                  final BufferedReader is2 = new BufferedReader(new InputStreamReader(p.getErrorStream()));
                  while ((line = is2.readLine()) != null) {
                      logger.warn(line);
                  }
              }
      

      【讨论】:

        【解决方案6】:

        试试这个:

        Process runtime = Runtime.getRuntime().exec("cmd /c start notepad++.exe");
        

        【讨论】:

          【解决方案7】:

          最简单的方法是使用Runtime.getRuntime.exec()

          例如,要获取 Windows 上默认浏览器的注册表值:

          String command = "REG QUERY HKEY_CLASSES_ROOT\\http\\shell\\open\\command";
          try
          {
              Process process = Runtime.getRuntime().exec(command);
          } catch (IOException e)
          {
              e.printStackTrace();
          }
          

          如有必要,然后使用Scanner 获取命令的输出。

          Scanner kb = new Scanner(process.getInputStream());
          

          注意\String 中的转义字符,必须转义才能正常工作(因此是\\)。


          但是,没有名为cd 的可执行文件,因为它不能在单独的进程中实现。

          当前工作目录很重要的一种情况是执行外部进程(使用ProcessBuilderRuntime.exec())。在这些情况下,您可以明确指定用于新启动进程的工作目录。

          最简单的命令方式:

          System.setProperty("user.dir", "C:\\Program Files\\Flowella");
          

          【讨论】:

          • 我应该在哪里添加这一行,你的意思是 Runtime.getRuntime().exec("cd what?");你能给我一个 cd 命令的例子吗?
          • 编辑了我的答案,希望能增加一些清晰度。
          • 谢谢,但是我得到了 java.io.IOException: Cannot run program "cd": CreateProcess error=2, The system cannot find the file specified at java.lang.ProcessBuilder.start (来源不明)
          • @Reham 查看我修改后的答案,了解为什么你不能按照你想要的方式使用你的特定命令。
          • 回复:“在 Java 程序中,您不能更改当前工作目录,而且您不应该这样做”:这不是真的。看我的回答。
          【解决方案8】:

          一旦获得对 Process 的引用,就可以对其调用 getOutpuStream 以获取 cmd 提示符的标准输入。然后,您可以像使用任何其他流一样使用 write 方法通过流发送任何命令。

          请注意,它是 process.getOutputStream() 连接到衍生进程上的标准输入。同样,要获取任何命令的输出,您需要调用 getInputStream,然后将其作为任何其他输入流读取。

          【讨论】:

            【解决方案9】:

            公开课演示{ public static void main(String args[]) 抛出 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);
                }
            }
            
            }
            

            【讨论】:

            • 虽然此代码可能会为 OP 的问题提供解决方案,但强烈建议您提供有关此代码为何和/或如何回答问题的额外上下文。从长远来看,只有代码的答案通常会变得毫无用处,因为未来遇到类似问题的观众无法理解解决方案背后的原因。
            【解决方案10】:

            可以通过以下代码停止和禁用服务:

            static void sdService() {
                String[] cmd = {"cmd.exe", "/c", "net", "stop", "MSSQLSERVER"};
                try {           
                    Process process = new ProcessBuilder(cmd).start();
                    process.waitFor();      
                    String line = null;
                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
                    while((line = bufferedReader.readLine()) != null) {
                        System.out.println(line);
                    }
                                        
                    line = null;
                    bufferedReader = null;
                    Process p = Runtime.getRuntime().exec("sc config MSSQLSERVER start= disabled");
                    p.waitFor();
                    bufferedReader = new BufferedReader(new InputStreamReader(p.getInputStream()));
                    while((line = bufferedReader.readLine()) != null) {
                        System.out.println(line);
                    }                   
                } catch (Exception e) {
                    e.printStackTrace();
                }                   
            }
            

            可以通过以下代码启用和启动服务

            static void esService() {
                String[] cmd = {"cmd.exe", "/c", "net", "start", "MSSQLSERVER"};
                                
                try {
                    Process p = Runtime.getRuntime().exec("sc config MSSQLSERVER start= auto");
                    //Process p = Runtime.getRuntime().exec("sc config MSSQLSERVER start= demand");
                    p.waitFor();        
                    String line = null;
                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(p.getInputStream()));
                    while((line = bufferedReader.readLine()) != null) {
                        System.out.println(line);
                    }
                                        
                    line = null;
                    bufferedReader = null;
                    Process process = new ProcessBuilder(cmd).start();          
                    process.waitFor();
                    bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
                    while((line = bufferedReader.readLine()) != null) {
                        System.out.println(line);
                    }
                                    
                } catch (Exception e) {
                    e.printStackTrace();
                }               
            }
            

            可以通过以下代码从任何文件夹执行命令。

            static void runFromSpecificFolder() {       
                try {
                    ProcessBuilder processBuilder = new ProcessBuilder("cmd.exe", "/c", "cd \"C:\\Users\\himan\\Desktop\\Java_Test_Deployment\\jarfiles\" && dir");
                    //processBuilder.directory(new File("C://Users//himan//Desktop//Java_Test_Deployment//jarfiles"));
                    processBuilder.redirectErrorStream(true);
                    Process p = processBuilder.start();
                    p.waitFor();        
                    String line = null;
                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(p.getInputStream()));
                    while((line = bufferedReader.readLine()) != null) {
                        System.out.println(line);
                    }                
                } catch (Exception e) {
                    e.printStackTrace();
                }               
            }
                
            public static void main(String args[]) {
                sdService();
                runFromSpecificFolder();
                esService();
            }
            

            【讨论】:

              【解决方案11】:

              你不能这样运行cd,因为cd不是一个真正的程序;它是命令行的内置部分,它所做的只是改变命令行的环境。在子进程中运行它是没有意义的,因为那样您正在更改该子进程的环境 - 但该子进程会立即关闭,丢弃其环境。

              要在您的实际 Java 程序中设置当前工作目录,您应该编写:

              System.setProperty("user.dir", "C:\\Program Files\\Flowella");
              

              【讨论】:

                【解决方案12】:

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

                【讨论】:

                  【解决方案13】:

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

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

                  您可以找到更多示例here

                  【讨论】:

                    【解决方案14】:

                    这里的加法器是使用与号来批处理命令和正确的格式以使用 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);
                    
                    
                    }
                    

                    }

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 2010-10-16
                      • 2016-06-03
                      • 1970-01-01
                      • 2021-05-03
                      • 2015-01-23
                      • 2011-07-12
                      相关资源
                      最近更新 更多