如何在单个 cmd 窗口中使用 Java Runtime 执行 cd 命令

3

我需要将以下的切换目录命令在cmd提示符中执行,但是要用java来执行它们。dir命令可以正常工作,但是cd命令不能。我必须在一个单独的cmd窗口中执行它们。

cd inputDir
dir
cd outputDir
和是来自Windows的目录。

Java 代码片段:

ArrayList<String> dosCommands = new ArrayList<String>();
Process p;
for (int i=0;i< dosCommands.size();i++){
    p=Runtime.getRuntime().exec("cmd.exe /c "+dosCommands.get(i)); 
    p.waitFor();
    BufferedReader reader=new BufferedReader(new InputStreamReader(p.getInputStream()));
    String line=reader.readLine();
    while(line!=null) 
    { 
        System.out.println(line); 
        line=reader.readLine(); 
    } 
}

更新

将参数更改为cmd.exe /k而不是/c

p=Runtime.getRuntime().exec("cmd.exe /k "+dosCommands.get(i)); 

我不得不删除

p.waitFor(); 

方法,因为我在其中遇到了困难。 这样做,我现在会卡在闭合标签 </p> 处。
line.reader.readLine(); 

1
你能详细描述一下“不起作用”是什么意思吗?你能提供一些代码输出以及你期望发生的情况吗? - Ivan Mushketyk
命令可以执行,但是没有任何回应。命令执行后,cmd.exe会关闭。 - chris
@IvanMushketyk 是的,当我执行cd inputDir时,它应该切换到输入目录的目录。我通过在cd inputDir之后执行dir命令来检查它。不幸的是,dir命令打印了另一个目录。 - Eduardox23
你是否偶然从一个分区更改到另一个分区的目录?如果是这样,你需要先使用“cd <分区字母>”命令,然后再使用“cd <目标路径>”命令。 - Ivan Mushketyk
以下是我尝试执行的一些cd命令: cd C:\Users\eleite\Workspace\RunCmd\Petrel_Logs cd C:\Users\eleite\Workspace\RunCmd\Petrel2014LicenseModuleLogging - Eduardox23
3个回答

2

使用

cmd.exe /K

不是
cmd.exe /c

您可以在此处找到有关命令参数的更多信息:cmd params

使用 /c,cmd会完成并退出。使用 /k,则不会退出。

__更新__

我的意思是:

cd inputDir
dir
cd outputDir
exit

请注意最后一行。

__更新2__

请在您的代码中使用类似的内容,以查找根据运行进程当前工作目录:

public class JavaApplication1 {
  public static void main(String[] args) {
       System.out.println("Working Directory = " +
              System.getProperty("user.dir"));
  }
}

在此之后,让我们确保您试图进入的文件夹存在于该文件夹中。

那似乎是解决方案的一条路径,但现在我无法读取一行的输出并卡在了p.waitFor()。 - Eduardox23
你尝试在批处理文件的末尾添加一个退出语句了吗? - Alp
我需要在一个命令窗口中执行所有的命令,而不是逐个执行。 - Eduardox23
@Eduardox23 这是代码示例:http://ideone.com/KjVOjc(在ideone上无法工作,但应该可以在您的Windows上工作)。 - Pshemo
@Eduardox23 你有取得任何进展吗?如果有,请更新你的问题,以便我们了解你的进展。如果没有,请发布运行脚本后的操作(例如屏幕截图、错误等)。 - Alp
@alp 我已经更新了问题,但不幸的是我没有取得任何进展。我已经在cmd窗口中测试了这些命令,它们可以正常工作,但是当作为参数传递给Java时却无法正常工作。 - Eduardox23

1
尝试这个实验:打开一个命令行窗口(使用鼠标和/或键盘,不要用代码)。现在使用类似于cd \cd C:\Windows的命令切换到另一个目录。
然后打开第二个命令行窗口。它的当前目录是什么?它是否记得你在第一个命令行窗口中所做的操作?
它没有记住,因为每次运行cmd.exe都会启动一个新进程,具有自己的当前目录状态。
在你的代码中,你在每次for循环迭代中执行了一个新的cmd.exe进程。每次启动新的cmd.exe时,它都不知道其他cmd.exe实例中可能存在的当前目录。
你可以设置进程执行的当前目录:
String inputDir = "C:\\Users\\eleite\\Workspace\\RunCmd\\Petrel_Logs";
p = Runtime.getRuntime().exec("cmd.exe /c " + dosCommands.get(i),
    null, inputDir); 

是的,你说得对。有没有一种方式可以在单个命令行窗口中执行所有命令?这样我就不必通过命令传递目录了。 - Eduardox23
将命令写入 .bat 文件,并将其传递给 cmd.exe /c。 - VGR
@Eduardox23 你可以通过输入流将每个命令传递给处理控制台。如果您不想在主线程中执行此操作,则可以创建单独的线程来完成。 - Pshemo
@vgr 我不想使用 .bat 文件,我希望所有的命令都在 Java 代码中。 - Eduardox23
@Pshemo,抱歉我没明白,你能提供一个例子吗? - Eduardox23

0

如果你想要

  • 创建模拟控制台的进程
  • 并让该控制台执行几个命令
  • 在这些命令执行完后,继续从主线程中执行代码

那么可以尝试使用以下代码:

ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/k");
pb.redirectOutput(Redirect.INHERIT);//redirect process output to System.out
pb.redirectError(Redirect.INHERIT);//redirect process output to System.err
Process p = pb.start();

try(PrintWriter pw = new PrintWriter(new OutputStreamWriter(p.getOutputStream()), true)){
    pw.println("dir");//execute command 1, for instance "dir"
    pw.println("ver");//execute command 2, for instance "ver"
    //... rest of commands
    pw.println("exit");//when last command finished, exit console
}
p.waitFor();//this will make main thread wait till process (console) will finish (will be closed)
//here we place rest of code which should be executed after console after console process will finish
System.out.println("---------------- after process ended ----------------");

如果你想要执行的命令列表,只需将它们放在这里:

try(PrintWriter pw = new PrintWriter(new OutputStreamWriter(p.getOutputStream()), true)){

    //here and execute them like 
    for (String command : dosCommands){
        pw.println(command);
    }        

    pw.println("exit");//when last command finished, exit console
}

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