java - 如何在 Windows 上的 Java 中使用 vt100 转义码

标签 java windows cmd vt100

vt100 转义码是一种功能强大且流行的方法,用于在 xterm 或 konsole 等虚拟终端上格式化输出(颜色、定位、闪烁、下划线等)。参见 https://en.wikipedia.org/wiki/ANSI_escape_code

当你在 xterm、konsole 等中运行一个 java 程序和 System.out.print 这样的代码——例如

// print "Hello, World!" in red
System.out.print("\u001b[31mHello, World!");

java 将它们原封不动地传递给终端,因此这些终端随后会解释代码并按照您的预期运行。

虽然 Java 程序应该是独立于平台的,但是当您从 Windows 命令提示符运行这样的程序时,您会看到打印出来的代码,如下所示:

☐[31mHello, World!

在寻找解决这个问题的方法后,我找不到简单的解决方案,甚至找不到关于该主题的讨论。大多数解决方案取决于在不同的控制台应用程序中运行您的程序,或将基于 Java 的自定义控制台包含到您的程序中。

那么 - 如何在 Windows 默认命令提示符下轻松使用 vt100 格式的文本?

最佳答案

我不知道这是否适用于旧版本的 Windows(欢迎提供一些反馈 - 我已经在 Windows 10 上对其进行了测试),但我已经从 https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences 的底部获取了代码并将其翻译成 Java。

这使用了对 kernel32.dll 的一些调用,因此我必须合并 Java Native Access (JNA)。要运行它,您需要下载 jna-*version*.jarjna-platform-*version*.jar https://github.com/java-native-access/jna#download并将它们包含在您的项目中。

然后,添加这些导入:

import com.sun.jna.*;
import com.sun.jna.platform.win32.WinDef.*;
import com.sun.jna.platform.win32.WinNT.HANDLE;

在程序的开头,您可以通过运行以下代码来启用 vt100:

if(System.getProperty("os.name").startsWith("Windows"))
{
    // Set output mode to handle virtual terminal sequences
    Function GetStdHandleFunc = Function.getFunction("kernel32", "GetStdHandle");
    DWORD STD_OUTPUT_HANDLE = new DWORD(-11);
    HANDLE hOut = (HANDLE)GetStdHandleFunc.invoke(HANDLE.class, new Object[]{STD_OUTPUT_HANDLE});

    DWORDByReference p_dwMode = new DWORDByReference(new DWORD(0));
    Function GetConsoleModeFunc = Function.getFunction("kernel32", "GetConsoleMode");
    GetConsoleModeFunc.invoke(BOOL.class, new Object[]{hOut, p_dwMode});

    int ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4;
    DWORD dwMode = p_dwMode.getValue();
    dwMode.setValue(dwMode.intValue() | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
    Function SetConsoleModeFunc = Function.getFunction("kernel32", "SetConsoleMode");
    SetConsoleModeFunc.invoke(BOOL.class, new Object[]{hOut, dwMode});
}

从那时起

System.out.print("\u001b[31mHello, World!");

将打印“Hello, World!”正如预期的那样呈红色。

关于java - 如何在 Windows 上的 Java 中使用 vt100 转义码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52767585/

相关文章:

java - 在保留唯一性的同时缩短 java UUID

windows - 追踪在 Windbg 中创建对象的堆栈跟踪

windows - 静态链接的应用程序 - 无效或损坏的 dll

javascript - 控制台写入速度会影响程序执行速度吗

javascript - PhantomJS:cygwin 返回与 Windows cmd 不同的 JS 日期

java - 有没有更好的方法来实现具有两个条件的简单工厂?

java - scala 和 java 数组

java - 获取Android中某个接口(interface)的所有实现的列表

windows - 易于使用的可移植可执行恶意软件调试器

c - 通过CMD复制时系统找不到指定的文件