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

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

问题描述

这篇文章提供一个解决方案来检索Windows下正在运行的进程的列表。它本质上是:

  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);

然后读取输入。



看起来和工作伟大,但我想知道是否有可能,任务列表使用的字符集可能不是默认字符集,并且这个调用可能失败?



例如< a href =http://stackoverflow.com/questions/457655/java-charset-and-windows>这个关于不同可执行文件的其他问题显示它可能会导致一些问题。

$ b

解决方案

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

可以将其分为2部分:


  1. 窗口部分

    从java执行Windows命令 - 在Windows land中的jvm外部。当java Runtime类执行一个windows命令时,它使用DLL控制台&因此出现在窗口,就像命令在控制台中运行

    问:当我在控制台中运行C:\windows \system32\tasklist.exe时,字符编码是什么(在Windows术语中的代码页)?




    • 给出控制台的活动代码页号(例如,850为多语言拉丁文-1,1252为拉丁文-1)。请参见 Windows Microsoft代码页 Windows OEM代码页 Windows ISO代码页

      默认系统代码页最初是根据您的系统区域设置(输入systeminfo以查看此或控制面板 - >区域和语言)。

    • OS / .NET函数 getACP()还提供此信息

      $ b
    • java部分:

      如何从x(例如850或1252)的Windows代码页解码java字节流?




      • Windows代码页码和等效的java字符集名称之间的完整映射可以从此处 - 代码页标识符(Windows)

      • 但是,实际上可以添加以下前缀之一来实现映射:对于ISO,为IBM或x-IBM,对于OEM,为windows-或 x-windows-用于Microsoft / Windows。

        例如ISO-8859-1或IBM850或Windows-1252


完整解决方案: / p>

  String cmd = System.getenv(windir)+\\system32\\+chcp。 com; 
Process p = Runtime.getRuntime()。exec(cmd);
//在这里使用默认字符集 - 只需要核心UTF8 / UTF16的数字;
//忽略在:之前的文本
String windowCodePage = new Scanner(
new InputStreamReader(p.getInputStream()))skip(。*:)。

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(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);

//调试输出
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);
}

感谢Q! - 很有趣。


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);

then reads the input.

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?

解决方案

Can break this into 2 parts:

  1. The windows part
    From java you're executing a Windows command - externally to the jvm in "Windows land". When java Runtime class executes a windows command, it uses the DLL for consoles & so appears to windows as if the command is running in a console
    Q: When I run C:\windows\system32\tasklist.exe in a console, what is the character encoding ("code page" in windows terminology) of the result?

    • windows "chcp" command with no argument gives the active code page number for the console (e.g. 850 for Multilingual-Latin-1, 1252 for Latin-1). See Windows Microsoft Code Pages, Windows OEM Code Pages, Windows ISO Code Pages
      The default system code page is originally setup according to your system locale (type systeminfo to see this or Control Panel-> Region and Language).
    • the windows OS/.NET function getACP() also gives this info

  2. The java part:
    How do I decode a java byte stream from the windows code page of "x" (e.g. 850 or 1252)?

    • the full mapping between windows code page numbers and equivalent java charset names can be derived from here - Code Page Identifiers (Windows)
    • However, in practice one of the following prefixes can be added to achieve the mapping:
      "" (none) for ISO, "IBM" or "x-IBM" for OEM, "windows-" OR "x-windows-" for Microsoft/Windows.
      E.g. ISO-8859-1 or IBM850 or windows-1252

Full Solution:

    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天全站免登陆