您如何在 Java 中写入命令提示符?
How do you write to a command prompt in Java?
背景
我从 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();
我不确定为什么没有将命令写入弹出的命令提示符。我看到弹出了一个新的命令提示符,但目录从开始的地方没有变化。如何将命令输入到我生成的提示中?
您的程序 ProcessBuilder 使您可以访问进程的标准输入、标准输出和标准错误 cmd.exe。这些与程序 cmd.exe
打开的 window 和命令提示符的输入和输出不同
这里有一个关于如何用 c# 做的答案:
在 Java 中,我不知道类似的 API,它实际上可能需要使用 JNI 或 JNA 才能访问 Windows APIs你需要使用。您使用的函数(通过 JNI 或 JNA)与其他答案中引用的 https://docs.microsoft.com/en-us/windows/console/allocconsole 相同。所以这是一种方法,但是如果您选择走那条路,那么如何使用 JNI 或 JNA 的完整描述不在此处的答案范围之内。
当您写入 p
时,您正在写入此命令的标准输入:
cmd.exe /c start cmd.exe
您正在写信给 第一个 cmd.exe
。除了启动第二个之外,它什么都不做。不可能(至少不简单)获得第二个进程的句柄。您可以使用 /K
,然后将命令与 &&
合并。例如:
commands.add("/K");
commands.add(String.join(" && ", OTHER_COMMANDS_AS_LIST));
据我所知,您正在尝试实现与远程 shell(没有网络且没有加密的 SSH)模糊相似的东西...
对于类似 *nix 的 shell,这应该像您期望的那样工作,因为那些 shell 正确地处理了它们的标准输入和输出,正是为了它们需要被重定向的情况(通过网络或其他方式)。
Windows其实cmd.exe并不是纯粹的shell。它是一个终端模拟器(屏幕上出现的黑色window)和shell,在一个进程中.这就是为什么它不从 stdin 获取输入,也不在 stdout 上打印输出的原因。相反,它监听输入的 GUI 键盘事件并在内部处理它们,输出直接显示在 window 中,而不将其写入标准输出。
这就是为什么没有简单的方法来 "remote control" 一个 cmd.exe。它不是为此而生的。
您可以尝试使用 "proper" shells,例如 Cygwin 的 bash.exe,或者 PowerShell,或类似的。
令人惊讶的是,大约 20 年前作为 quick'n'dirty "DOS window" 创建的 cmd.exe 至今仍然存在并实际用于生产工作.. .
背景
我从 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();
我不确定为什么没有将命令写入弹出的命令提示符。我看到弹出了一个新的命令提示符,但目录从开始的地方没有变化。如何将命令输入到我生成的提示中?
您的程序 ProcessBuilder 使您可以访问进程的标准输入、标准输出和标准错误 cmd.exe。这些与程序 cmd.exe
打开的 window 和命令提示符的输入和输出不同这里有一个关于如何用 c# 做的答案:
在 Java 中,我不知道类似的 API,它实际上可能需要使用 JNI 或 JNA 才能访问 Windows APIs你需要使用。您使用的函数(通过 JNI 或 JNA)与其他答案中引用的 https://docs.microsoft.com/en-us/windows/console/allocconsole 相同。所以这是一种方法,但是如果您选择走那条路,那么如何使用 JNI 或 JNA 的完整描述不在此处的答案范围之内。
当您写入 p
时,您正在写入此命令的标准输入:
cmd.exe /c start cmd.exe
您正在写信给 第一个 cmd.exe
。除了启动第二个之外,它什么都不做。不可能(至少不简单)获得第二个进程的句柄。您可以使用 /K
,然后将命令与 &&
合并。例如:
commands.add("/K");
commands.add(String.join(" && ", OTHER_COMMANDS_AS_LIST));
据我所知,您正在尝试实现与远程 shell(没有网络且没有加密的 SSH)模糊相似的东西...
对于类似 *nix 的 shell,这应该像您期望的那样工作,因为那些 shell 正确地处理了它们的标准输入和输出,正是为了它们需要被重定向的情况(通过网络或其他方式)。
Windows其实cmd.exe并不是纯粹的shell。它是一个终端模拟器(屏幕上出现的黑色window)和shell,在一个进程中.这就是为什么它不从 stdin 获取输入,也不在 stdout 上打印输出的原因。相反,它监听输入的 GUI 键盘事件并在内部处理它们,输出直接显示在 window 中,而不将其写入标准输出。
这就是为什么没有简单的方法来 "remote control" 一个 cmd.exe。它不是为此而生的。 您可以尝试使用 "proper" shells,例如 Cygwin 的 bash.exe,或者 PowerShell,或类似的。
令人惊讶的是,大约 20 年前作为 quick'n'dirty "DOS window" 创建的 cmd.exe 至今仍然存在并实际用于生产工作.. .