如何从 Windows 上的 Java 控制台应用程序确定当前活动的代码页?

Posted

技术标签:

【中文标题】如何从 Windows 上的 Java 控制台应用程序确定当前活动的代码页?【英文标题】:How to determine the currently active code page from a Java console application on Windows? 【发布时间】:2019-07-17 04:59:09 【问题描述】:

这是一个简单的 Java 应用程序,它在 Windows 上显示默认代码页

package doscommand;

import java.io.IOException;
import java.io.InputStream;

public class DosCommand 

    public static void main(String[] args) throws IOException 

        InputStream in = Runtime.getRuntime().exec("chcp.com").getInputStream();
        int ch;
        StringBuilder chcpResponse = new StringBuilder();
        while ((ch = in.read()) != -1) 
            chcpResponse.append((char) ch);
        
        System.out.println(chcpResponse); // For example: "Active code page: 437"
    

在我的 Windows 10 机器上,此应用程序始终显示 "Active code page: 437",因为 Cp437 是默认设置,Runtime.getRuntime().exec() 会在以下情况下启动新的 Process运行chcp.com

是否可以创建一个 Java 应用程序来代替显示 当前活动的代码页 用于运行代码的现有 命令提示符 窗口?

我希望能够从 命令提示符 执行类似的操作:

chcp 1252
java -jar "D:\NB82\DosCommand\dist\DosCommand.jar" REM Shows current code page is "1252".

chcp 850
java -jar "D:\NB82\DosCommand\dist\DosCommand.jar" REM  Shows current code page is "850".

How do you specify a Java file.encoding value consistent with the underlying Windows code page? 提出了类似的问题,但在这种情况下,OP 正在寻求非 Java 解决方案。

我更喜欢纯 Java 的解决方案,但作为替代方案:

这是否可以使用 JNI 通过调用一些可以访问 Windows API 的 C/C++/C# 代码来完成?被调用的代码只需要为活动代码页返回一个数值。 我会接受一个有说服力地认为无法完成的答案。

【问题讨论】:

如果这是我的问题,我会在 MSDN 中搜索 C/C++ 解决方案,然后使用 JNA 在 Java 中完成。或者更好的是,使用 C# 并完全跳过 Java 步骤。 ***.com/questions/54837058/… chcp.com 显示来自GetConsoleCP 的当前输入代码页。当前的输出代码页是GetConsoleOutputCP,但 chcp.com 不使用它。设置代码页时,它通过SetConsoleCPSetConsoleOutputCP 设置与输入和输出代码页相同的值。 @HovercraftFullOfEels Re "use JNA to do it in Java" ,我听从了你的建议。由于它工作得很好,我将其中一个标签从 JNI 切换到了 JNA。 @eryksun GetConsoleCP() 工作完美。 【参考方案1】:

解决方案原来只是一行代码。 Using JNA,由 Windows API 函数 GetConsoleCP() 返回的值给出了控制台的活动代码页:

import com.sun.jna.platform.win32.Kernel32;

public class JnaActiveCodePage 

    public static void main(String[] args) 
        System.out.println("" + JnaActiveCodePage.getActiveInputCodePage());
    

    /**
     * Calls the Windows function GetConsoleCP() to get the active code page using JNA.
     * "jna.jar" and "jna-platform.jar" must be on the classpath.
     *
     * @return the code page number.
     */
    public static int getActiveInputCodePage() 
        return Kernel32.INSTANCE.GetConsoleCP();
    

【讨论】:

以上是关于如何从 Windows 上的 Java 控制台应用程序确定当前活动的代码页?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Java 从 Windows (MSCAPI) 上的智能卡获取用户身份?

从控制台/命令窗口断开java应用程序[重复]

如何使用 VB.net 获取 Windows 控制台应用程序的文本?

写入在 Windows 下的 Java 应用程序中生成的 C++ 控制台应用程序

从 Windows 上的 C# Service Fabric 应用程序连接到 docker_engine(命名管道)

关闭 Windows 控制台时如何优雅地关闭 Java 应用程序?