2012-02-08 9 views
6

Sto lavorando su un programma Java che deve recuperare il numero di serie della macchina, il numero di serie della CPU ecc. Su Windows, l'interfaccia WMI è il modo migliore per interrogare tali informazioni, e il modo standard per interrogare utilizzando la linea di comando èProcesso esterno avviato con ProcessBuilder/Runtime.exec() non riuscito su XP, funziona su Win 7

wmic bios get serialnumber 

che produce output:

SerialNumber 
WWV46RT609A3467173E 

Traducendo questo in Java, ho usato sia Runtime.exec () e un ProcessBuilder come questo: (The commented Proces s p è quello che ho fatto in precedenza). Qui, componente e oggetto corrispondono a "bios" e "serialnumber" nella riga di comando sopra.

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

Questo snippet funziona perfettamente su Windows 7, ma si blocca su Windows XP. L'uso di wmic dalla riga di comando funziona su entrambi i sistemi operativi. Ho letto here che c'è un problema con la gestione sia di stdout che di stderr del processo chiamato, da cui la chiamata redirectErrorStream().

Perché funziona in modo impeccabile su Windows 7 ma non funziona su XP? C'è un modo diverso dalla generazione di una discussione separata, alias "StreamGobbler"? (L'esempio legato a questo è molto antica, e precede la classe ProcessBuilder, con la sua redirectErrorStream call().

+0

prendere sempre uno stacktrace (jstack per esempio) quando il processo "si blocca". su una nota a fogli mobili: hai bisogno di 'break' dopo' ret = str.trim() ', tuttavia suppongo che su XP il comando entri in modalità interattiva – bestsss

+0

+1 per pubblicare una domanda per cui il primo commento * potrebbe * essere 'Leggi l'articolo JavaWorld' e mostrare la prova di averlo già letto. :) –

+0

@Andrew: Grazie :) Di solito posto una domanda solo quando sono completamente senza opzioni, (avendo stretto il collo di Google sull'argomento) o la cosa su cui sto lavorando è un po 'oscura o non ben documentata (come tutti i miei recenti su NSIS) – Rex

risposta

0

Devi usare le discussioni per catturare ouputs (errore standard &).

Si può anche dare un'occhiata a questo Apache library.

5

Spero che abbiate già una soluzione a questo problema. In caso contrario, questo è quello che dovete fare. In primo luogo, ho anche incontrato gli stessi problemi e ho scoperto che si tratta di problema bufferedReader Si trova in una situazione di deadlock che si traduce in Windows XP appeso. La soluzione è quella di simulare la fine della riga (Eof) al bufferrearea aggiungendo "<NUL" il comando.

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

+1. Questa risposta ha aiutato moltissimo la comunità di Minecraft! Un sacco di strumenti di Minecraft devono eseguire altre applicazioni e si imbattono in questo stesso identico problema su Windows XP. – Cybis

Problemi correlati