通过 Java 运行 cmd 命令

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

我找到了几个通过 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

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

java cmd cd
15个回答
157
投票

从不同目录运行进程到 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

15
投票

你可以试试这个:-

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

10
投票

如果你想执行像

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 将无法正确提供它们)。


9
投票

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

用法

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

4
投票

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

文件夹——文件。

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

3
投票

最简单的方法是使用

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
的可执行文件,因为它不能在单独的进程中实现。

当前工作目录很重要的一种情况是执行外部进程(使用

ProcessBuilder
Runtime.exec()
)。在这些情况下,您可以明确指定用于新启动进程的工作目录。

最简单的命令方式:

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

3
投票

试试这个:

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

2
投票

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

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


2
投票

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

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

1
投票

你不能这样运行

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

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

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

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

0
投票

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

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

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


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
投票

这里的增值器是使用与号来批处理命令和使用 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);


}

}


0
投票

(正如其他人所说) 对于简单的命令,您可以这样做,例如:

Runtime.getRuntime().exec("cmd /c mkdir H:\\test\\BBB");

(可能需要
cmd /c

但是,对于一些复杂的命令,你可能需要做一个double

cmd.exe /c cmd.exe /c
,
否则(如果你只使用 1)cmd 会静静地 dropped,
((或者如果你不使用
/c
或使用一些奇怪的
/c
cmd
组合模式,cmd可能会冻结)),
idk 为什么.

(((我怎么发现它?——我无法让它工作并尝试了多次;有一次不小心复制了cmd并运行它并找到了它。))

@例如::

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"
  // 
  // ---

}

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