An external process launched with ProcessBuilder / Runtime.exec () does not work in XP, works on Win 7

I am working on a Java program that should receive the serial number of the machine, the serial number of the processor, etc. On Windows, WMI is the best way to request this information, and the standard way to query using the command line

wmic bios get serialnumber 

which produces the conclusion:

 SerialNumber WWV46RT609A3467173E 

Translating this into Java, I used both Runtime.exec () and ProcessBuilder as follows: (The commented process p is what I did earlier). Here, the component and element correspond to "bios" and "serialnumber" on the command line 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 fine on Windows 7, but freezes on Windows XP. Using wmic from the command line works on both OSs. I read here that there is a problem with processing both the stdout and stderr of the called process, hence the call to redirectErrorStream ().

Why does it work flawlessly in Windows 7 but does not work on XP? Is there a way besides creating spawning of a separate stream, aka ' StreamGobbler '? (The linked example is quite ancient and precedes the ProcessBuilder class with a call to redirectErrorStream ().

+6
source share
2 answers

I hope you have a solution to this problem. If not, this is what you need to do. Firstly, I also ran into the same problems and came to the conclusion that this is a problem with the Reader buffer. It finds itself in a deadlock situation that causes Windows XP to freeze. The solution is to simulate the end of line (eof) for a buffered reader by adding the "<NUL" command.

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

You must use streams to capture pins (standard and errors).

You can also look at this Apache library .

0
source

Source: https://habr.com/ru/post/907919/


All Articles