【发布时间】:2012-02-29 17:45:13
【问题描述】:
我正在开发一个必须获取机器序列号、CPU 序列号等的 Java 程序。在 Windows 上,WMI 接口是查询此类信息的最佳方式,而使用命令行查询的标准方式是
wmic bios get serialnumber
产生输出:
SerialNumber
WWV46RT609A3467173E
将其翻译成 Java,我使用了 Runtime.exec() 和 ProcessBuilder,如下所示: (注释的 Process p 是我之前所做的)。这里,component 和 item 对应上面命令行中的 'bios' 和 'serialnumber'。
String ret = "";
ProcessBuilder pb = new ProcessBuilder("wmic", component, "get", item);
pb.redirectErrorStream(true);
// Process p = Runtime.getRuntime().exec(
// "wmic " + component + " get " + item);
Process p = pb.start();
InputStreamReader isr = new InputStreamReader(p.getInputStream());
BufferedReader input = new BufferedReader(isr);
String str;
while ((str = input.readLine()) != null) {
if (str.equalsIgnoreCase(item) || StringUtils.isBlank(str)) {
continue;
}
ret = str.trim();
}
input.close();
isr.close();
System.out.println(ret);
这个 sn-p 在 Windows 7 上完美运行,但在 Windows XP 上挂起。从命令行使用 wmic 可以在两个操作系统上使用。 我读到here 处理被调用进程的stdout 和stderr 存在问题,因此redirectErrorStream() 调用。
为什么它在 Windows 7 上可以完美运行,但在 XP 上却失败了?除了产生一个单独的线程,又名'StreamGobbler'之外,还有其他方法吗? (链接的例子很古老,早于 ProcessBuilder 类,它的 redirectErrorStream() 调用。
【问题讨论】:
-
总是在进程“挂起”时进行堆栈跟踪(例如 jstack)。顺便说一句:你需要在
ret = str.trim()之后break,但我的猜测是在 XP 上该命令只是进入交互模式 -
+1 用于发布一个明显的第一条评论可能是“阅读 JavaWorld 文章”的问题,并显示已经阅读过它的证据。 :)
-
@Andrew:谢谢 :) 我通常只在我完全没有选择的情况下发布一个问题,(在这个话题上让谷歌绞尽脑汁)或者我正在做的事情有点晦涩难懂或者没有很好的记录(就像我最近在 NSIS 上的所有记录一样)
标签: java windows process windows-xp