以字符集安全的方式获取 Windows 上的进程列表 [英] Get list of processes on Windows in a charset-safe way

查看:12
本文介绍了以字符集安全的方式获取 Windows 上的进程列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这篇文章 给出了在 Windows 下检索正在运行的进程列表的解决方案.本质上是这样的:

This post gives a solution to retrieve the list of running processes under Windows. In essence it does:

String cmd = System.getenv("windir") + "\system32\" + "tasklist.exe";
Process p = Runtime.getRuntime().exec(cmd);
InputStreamReader isr = new InputStreamReader(p.getInputStream());
BufferedReader input = new BufferedReader(isr);

然后读取输入.

它看起来和工作得很好,但我想知道是否有可能 tasklist 使用的字符集可能不是默认字符集并且这个调用可能会失败?

It looks and works great but I was wondering if there is a possibility that the charset used by tasklist might not be the default charset and that this call could fail?

例如关于不同可执行文件的另一个问题表明它可能会导致一些问题.

For example this other question about a different executable shows that it could cause some issues.

如果是这样,有没有办法确定合适的字符集是什么?

If that is the case, is there a way to determine what the appropriate charset would be?

推荐答案

可以把它分成两部分:

  1. 窗户部分
    您正在从 java 执行 Windows 命令 - 在Windows land"中的 jvm 外部.当 java Runtime 类执行 windows 命令时,它使用控制台的 DLL &所以在 Windows 中看起来好像命令在控制台中运行
    问:当我在控制台中运行 C:windowssystem32 asklist.exe 时,结果的字符编码(Windows 术语中的代码页")是什么?

  • windows "chcp" 命令不带参数给出控制台的活动代码页号(例如,850 表示多语言拉丁语 1,1252 表示拉丁语 1).请参阅 Windows Microsoft 代码页Windows OEM 代码页Windows ISO 代码页>
    默认系统代码页最初是根据您的系统区域设置设置的(键入 systeminfo 以查看此内容或控制面板-> 区域和语言).
  • windows OS/.NET 函数 getACP() 也提供此信息

  • java部分:
    如何从x"的 windows 代码页(例如 850 或 1252)解码 java 字节流?

    • windows 代码页号和等效 java 字符集名称之间的完整映射可以从 此处 - 代码页标识符 (Windows)
    • 但是,实际上可以添加以下前缀之一来实现映射:
      "(无)用于 ISO,IBM"或x-IBM"用于 OEM,windows-"或x-windows-"用于 Microsoft/Windows.
      例如.ISO-8859-1 或 IBM850 或 windows-1252

    完整解决方案:

        String cmd = System.getenv("windir") + "\system32\" + "chcp.com";
        Process p = Runtime.getRuntime().exec(cmd);
        // Use default charset here - only want digits which are "core UTF8/UTF16"; 
        // ignore text preceding ":"
        String windowsCodePage = new Scanner(
            new InputStreamReader(p.getInputStream())).skip(".*:").next();
    
        Charset charset = null;
        String[] charsetPrefixes = 
            new String[] {"","windows-","x-windows-","IBM","x-IBM"};
        for (String charsetPrefix : charsetPrefixes) {
            try {
                charset = Charset.forName(charsetPrefix+windowsCodePage);
                break;
            } catch (Throwable t) {
            }
        }
        // If no match found, use default charset
        if (charset == null) charset = Charset.defaultCharset();
    
        cmd = System.getenv("windir") + "\system32\" + "tasklist.exe";
        p = Runtime.getRuntime().exec(cmd);
        InputStreamReader isr = new InputStreamReader(p.getInputStream(), charset);
        BufferedReader input = new BufferedReader(isr);
    
        // Debugging output
        System.out.println("matched codepage "+windowsCodePage+" to charset name:"+
                charset.name()+" displayName:"+charset.displayName());
        String line;
        while ((line = input.readLine()) != null) {
               System.out.println(line);
        }
    

    感谢您的提问!- 很有趣.

    Thanks for the Q! - was fun.

    这篇关于以字符集安全的方式获取 Windows 上的进程列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆