【问题标题】:External process launched with ProcessBuilder/Runtime.exec() fails on XP, works on Win 7使用 ProcessBuilder/Runtime.exec() 启动的外部进程在 XP 上失败,在 Win 7 上有效
【发布时间】: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


【解决方案1】:

我希望您现在已经解决了这个问题。如果没有,这就是你需要做的。首先,我也遇到了同样的问题,发现是bufferedReader问题。它陷入僵局,导致 windows xp 挂起。解决方案是通过在命令后面附加"<NUL" 来模拟缓冲读取器的行尾(eof)。

 String[] command = {"CMD", "/C", "WMIC COMPUTERSYSTEM GET USERNAME <NUL "} and executing this command. 

【讨论】:

  • +1。这个答案极大地帮助了 Minecraft 社区!许多 Minecraft 工具必须运行其他应用程序,并且它们在 Windows XP 上遇到了完全相同的问题。
【解决方案2】:

您必须使用线程来捕获输出(标准和错误)。

你也可以看看这个Apache library。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-06
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    • 2013-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多