【问题标题】:How to run multiple cmd commands through Java?如何通过Java运行多个cmd命令?
【发布时间】:2021-05-03 19:18:06
【问题描述】:

我有一个简单的 GUI,可以选择一个可执行文件和一个批处理文件。单击“运行”应该启动一个命令行实例,然后运行给定选定批次的可执行文件。然而,打嗝似乎出现在不同的地方。这是相关代码sn -p:

String[] commands = {"cmd.exe", "/c", "C:\\Xilinx\\14.7\\ISE_DS\\settings64.bat && cd /d ",
                "\"" + simFile.getParent() + "\"", " && ping localhost && ",
                "\"" + jTextField1.getText() + "\"",  " -tclbatch \"" + jTextField2.getText() + "\""};

ProcessBuilder simBuilder = new ProcessBuilder(commands);
simBuilder.redirectErrorStream(true);
Process simulation = simBuilder.start();

BufferedReader reader = new BufferedReader(new InputStreamReader(simulation.getInputStream()));
String line;
while (true) {
    line = reader.readLine();
    if (line == null)
        break;
    System.out.println(line);
}

我选择通过 ProcessBuilder 而不是“Runtime.getRuntime().exec”来创建进程,因为将命令和参数作为字符串数组更具可读性和可管理性。我浏览了 Runtime、Process 和 ProcessBuilder 的文档。我还搜索了类似的问题,以下是最接近的:Run cmd commands through Java。但是,我仍然无法让所有命令正常运行(如果有的话)。第一点:程序成功执行命令,直到“ping”,我放置它以确定问题发生的位置。我通过 BufferedReader 在控制台中获得 cmd 输出就好了。但是,下一个命令应该运行由“jTextField1.getText()”指示的可执行文件,尽管我确保路径在转义的双引号内,但会给出“文件名、目录名或卷标语法不正确”的错误占空间。它在我的语法中吗?与放置双&符号的位置有关吗?是否每个带有参数的单独命令都需要是数组中自己的字符串?我尝试了不同的方法,但似乎总是导致错误。

【问题讨论】:

    标签: java command-line process windows-10


    【解决方案1】:

    您应该检查您的路径名称是否正确,并尝试将 cmd 作为一个参数值,而不是在cmd.exe /c 之后以逗号分隔。这将确保将参数正确传递给 CMD 作为 CMD shell 处理的单个参数:

    import java.nio.file.Files
    System.out.println("Files.isDirectory(simFile.getParent())="+Files.isDirectory(simFile.getParent()));
    System.out.println("Files.isExecutable(jTextField1.getText())="+Files.isExecutable(Path.of(jTextField1.getText())));
    
    String cmd = "C:\\Xilinx\\14.7\\ISE_DS\\settings64.bat && cd /d "+
                "\"" + simFile.getParent() + "\" && ping localhost && "+
                "\"" + jTextField1.getText() + "\" -tclbatch \"" + jTextField2.getText() + "\"";
    String[] commands = {"cmd.exe", "/c", cmd};
    

    【讨论】:

    • 谢谢。我在前两行有错误,所以我跳过了尝试。但是将所有命令放在一个字符串中确实有效。请问是什么原因?此外,出于某种原因,从字符串数组中排除“/c”似乎会使整个程序卡住而不显示任何内容。没有按钮可以按下,甚至退出按钮也无济于事,所以我必须使用任务管理器。它显示 cmd 行作为 java 应用程序的子进程运行,因此它似乎卡在后台。使用“/k”代替运行并显示所有命令的结果,但随后卡住。
    • 也许您的 UI 冻结的原因是您在主 UI 事件循环/线程中运行此操作处理程序。如果是这样,请在后台线程中尝试,并在按钮运行时禁用该按钮。
    • 我明白了。这就说得通了。如果我不麻烦,在单独的线程中执行读取和写入的适当方法是什么?据我了解,如果我在主线程中创建缓冲读取器(用于 cmd 常规和错误输出)和写入器,我将无法将它们的引用传递给将使用它们的自定义线程类,因为 Java 按值传递。或者,如果我让读者在自定义线程类定义中,我不知道是否可以让他们访问主类中定义的进程(NetBeans 告诉我这样做时没有这样的进程)。
    • 我找到了解决多线程问题的方法。我对 Java 中按值传递的理解是有缺陷的。在传递对象变量时,Java 按值传递它们的引用。因此,方法/构造函数将获得对同一对象的引用并能够使用其方法。我可以很好地通过 BufferedReader,并且线程按预期进行了读取。我还发现我可以将写作功能保留在主线程中。
    猜你喜欢
    • 2021-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-08
    • 1970-01-01
    相关资源
    最近更新 更多