6

I am working on a Java program that has to fetch the machine serial number, CPU serial number etc. On Windows, the WMI interface is the best way to query for such information, and the standard way to query using the commandline is

wmic bios get serialnumber

which produces output:

SerialNumber
WWV46RT609A3467173E

Translating this into Java, I have used both Runtime.exec() and a ProcessBuilder like so: (The commented Process p is what I did previously). Here, component and item correspond to 'bios' and 'serialnumber' in the commandline above.

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

This snippet works perfectly on Windows 7, but hangs on Windows XP. Using wmic from the commandline works on both OSes. I read here that there's a problem with handling both stdout and stderr of the called process, hence the redirectErrorStream() call.

Why does it work flawlessly on Windows 7 but fail on XP? Is there a way other than spawning a separate thread, aka 'StreamGobbler'? (The linked example is quite ancient, and predates the ProcessBuilder class, with its redirectErrorStream() call.

Community
  • 1
  • 1
Rex
  • 801
  • 1
  • 17
  • 26
  • always take a stacktrace (jstack for instance) when the process "hangs". on a flip note: you need `break` after `ret = str.trim()` , yet my guess is that on XP the command just enters into interactive mode – bestsss Feb 08 '12 at 09:48
  • +1 for posting a question for which the obvious 1st comment *could* be 'Read the JavaWorld article', and showing evidence of already having read it. :) – Andrew Thompson Feb 08 '12 at 09:57
  • @Andrew: Thanks :) I usually post a question only when I'm totally out of options, (having wrung Google's neck on the topic) or the thing I'm working on is a bit obscure or not well documented(like all my recent ones on NSIS) – Rex Feb 08 '12 at 10:12

2 Answers2

7

I hope that you have by now got a resolution to this issue. If not, this is what you need to do. First, I also encountered with the same issues and came to discover that it is bufferedReader issue. It is gets into a deadlock situation that resulting into windows xp hanging. The solution is to simulate the end of line (eof) to the bufferedreader by appending "<NUL" the the command.

 String[] command = {"CMD", "/C", "WMIC COMPUTERSYSTEM GET USERNAME <NUL "} and executing this command. 
Taryn
  • 242,637
  • 56
  • 362
  • 405
  • +1. This answer has helped the Minecraft community tremendously! Lots of Minecraft tools have to run other applications, and they run into this exact same issue on Windows XP. – Cybis Dec 04 '12 at 07:44
0

You have to use threads to capture ouputs (standard & error).

You can also take a look at this Apache library.

ndeverge
  • 21,378
  • 4
  • 56
  • 85