【问题标题】:How do you write to a command prompt in Java?如何在 Java 中写入命令提示符?
【发布时间】:2020-05-20 19:59:11
【问题描述】:

背景

我从 Java 应用程序启动了命令提示符。现在我想在刚刚生成的命令提示符中输入命令。如何在 Java 程序刚刚生成的提示符下运行命令?

我的尝试

我的代码创建了一个启动命令提示符的进程。然后它获取进程的 OutputStream 来尝试写入它。但我没有看到任何变化发生。它应该只是更改目录,然后在新目录中运行一系列命令。

// Block that makes new command prompt
List<String> commands = new ArrayList<String>();
commands.add("cmd.exe");
commands.add("/c");
commands.add("start");
commands.add("cmd.exe");

// Block that creates a writer to write to new command prompt
ProcessBuilder pb = new ProcessBuilder(commands);
Process p = pb.start();
OutputStream os = p.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os)); 

// Block that actually writes the commands
writer.write(String.format("cd %s\n", PATH);
writer.write(OTHER_COMMANDS); // I'm ommiting the other commands because there's a lot
writer.flush();
writer.close();

我不确定为什么这些命令没有写入弹出的命令提示符。我看到弹出了一个新的命令提示符,但目录从它开始的地方没有改变。如何在我生成的提示中输入命令?

【问题讨论】:

    标签: java command-line command-prompt


    【解决方案1】:

    当你写信给p时,你写的是这个命令的标准输入:

    cmd.exe /c start cmd.exe
    

    您正在写信给 first cmd.exe。除了开始第二个之外,它什么都不做。获得第二个进程的句柄是不可能的(至少不简单)。您可以使用/K,并将命令与&amp;&amp; 一个接一个地合并。例如:

    commands.add("/K");
    commands.add(String.join(" && ", OTHER_COMMANDS_AS_LIST));
    

    【讨论】:

    • 那么,有什么方法可以让命令直接从第一个 cmd.exe 运行? (为了更简洁的代码)。我得到了这个方法,但它看起来更像是一种解决方法,而不是它的意图。
    • 据我所知,这是不可能的。
    【解决方案2】:

    您的程序 ProcessBuilder 使您可以访问进程 cmd.exe 的标准输入、标准输出和标准错误。这些与程序cmd.exe打开的窗口和命令提示符的输入和输出不同

    这里有一个关于如何使用 c# 的答案:Create a cmd window and write to it from C# application

    在 Java 中,我不知道有类似的 API,它实际上可能需要使用 JNI 或 JNA 才能访问您需要使用的 Windows API。您使用的函数(通过 JNI 或 JNA)将与其他答案中引用的 https://docs.microsoft.com/en-us/windows/console/allocconsole 相同。所以这是一种方法,但是如果您选择走这条路,那么如何使用 JNI 或 JNA 的完整描述超出了这里的答案范围。

    【讨论】:

      【解决方案3】:

      据我所知,您正在尝试实现类似于远程 shell 的东西(没有网络和加密的 SSH)...

      这应该像您对 *nix-like shell 所期望的那样工作,因为这些 shell 正确地处理它们的标准输入和输出,正是在需要重定向它们的情况下(通过网络或其他方式)。

      Windows cmd.exe 实际上并不是一个纯 shell。它是一个终端模拟器(屏幕上出现的黑色窗口)外壳,在一个进程中。这就是为什么它没有从标准输入获得输入,也没有在标准输出上打印输出。相反,它侦听 GUI 键盘事件以获取输入并在内部处理它们,并且输出直接显示在窗口中,而无需将其写入标准输出。

      这就是为什么没有简单的方法来“远程控制”一个 cmd.exe。它不是为此而生的。 您可以使用“正确”的 shell 尝试此操作,例如 Cygwin 的 bash.exe,或者可能是 PowerShell 或类似的。

      令人惊讶的是,在大约 20 年前被创建为一个快速且肮脏的“DOS 窗口”的 cmd.exe 至今仍然存在并且实际上用于生产工作......

      【讨论】:

        猜你喜欢
        • 2017-10-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-08
        • 2014-04-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多