以字符集安全的方式获取 Windows 上的进程列表 [英] Get list of processes on Windows in a charset-safe way
问题描述
这篇文章 给出了在 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?
推荐答案
可以把它分成两部分:
窗户部分
您正在从 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屋!