2012-02-08 12 views
6

Estoy trabajando en un programa Java que tiene que buscar el número de serie de la máquina, el número de serie de la CPU, etc. En Windows, la interfaz WMI es la mejor manera para consultar dicha información, y la manera estándar de consulta utilizando la línea de comandos esProceso externo iniciado con ProcessBuilder/Runtime.exec() falla en XP, funciona en Win 7

wmic bios get serialnumber 

que produce la salida:

SerialNumber 
WWV46RT609A3467173E 

Traduciendo esto en Java, he utilizado tanto Runtime.exec () y un ProcessBuilder como ese: (El proceso comentado s p es lo que hice anteriormente). Aquí, el componente y el elemento corresponden a 'bios' y 'serialnumber' en la línea de comando anterior.

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

Este fragmento funciona perfectamente en Windows 7, pero se cuelga en Windows XP. Usar wmic desde la línea de comandos funciona en ambos sistemas operativos. He leído here que hay un problema con el manejo de stdout y stderr del proceso llamado, de ahí la llamada a redirectErrorStream().

¿Por qué funciona sin problemas en Windows 7 pero falla en XP? ¿Hay alguna otra forma que no sea el engendrar un hilo separado, también conocido como 'StreamGobbler'? (El ejemplo relacionado es bastante antiguo, y es anterior a la clase ProcessBuilder, con su llamado redirectErrorStream().

+0

siempre tome un stacktrace (jstack por ejemplo) cuando el proceso "cuelga". en una nota invertida: necesitas 'break' después de' ret = str.trim() ', pero supongo que en XP el comando simplemente ingresa al modo interactivo – bestsss

+0

+1 para publicar una pregunta para la cual el primer comentario obvio * podría * ser 'Leer el artículo de JavaWorld' y mostrar evidencia de haberlo leído. :) –

+0

@Andrew: Gracias :) Normalmente publico una pregunta solo cuando estoy totalmente sin opciones, (habiendo estrujado el cuello de Google sobre el tema) o en lo que estoy trabajando es un poco oscuro o no está bien documentado (como todos mis recientes en NSIS) – Rex

Respuesta

0

Usted tiene que usar hilos para capturar ouputs (& error estándar).

También puede echar un vistazo a esto Apache library.

5

Espero que ya tenga una solución a este problema. Si no, esto es lo que debe hacer. En primer lugar, también me encontré con los mismos problemas y descubrí que es problema bufferedReader .Esto se mete en una situación de estancamiento que resulta en la suspensión de Windows XP. La solución es simular el final de la línea (eof) al lector de búfer al agregar "<NUL" el comando.

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

+1. ¡Esta respuesta ha ayudado tremendamente a la comunidad de Minecraft! Muchas herramientas de Minecraft tienen que ejecutar otras aplicaciones, y se encuentran con este mismo problema en Windows XP. – Cybis

Cuestiones relacionadas