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.