【问题标题】:how to get motherboard serial number on GUI (in java)如何在 GUI 上获取主板序列号(在 java 中)
【发布时间】:2016-06-12 10:04:05
【问题描述】:

我确实想在文本字段(GUI 面板)中显示主板序列号。我创建了一个文本字段和操作按钮。我在操作按钮中编写了此代码。我在这段代码中犯了什么错误?

try {
        Process p = Runtime.getRuntime().exec("wmic baseboard get serialnumber");
        BufferedReader inn = new BufferedReader(new InputStreamReader(p.getInputStream()));

        while (true) {

            String line = inn.readLine();
            if (line == null) {
                break;
            }
            motherboard.setText(line);
        }
    } catch (Exception e) {
        JOptionPane.showMessageDialog(this, "Sorry could not found motherboard serial!");
    }

【问题讨论】:

  • 您不应忽略该异常。至少将其写入日志。在这种情况下,它会告诉您错误的原因。
  • 它无法告诉我什么是异常。当我在控制台中运行它时它运行良好但是当我尝试它时 gui 然后不工作并且不在 jTextfield 中显示
  • 我认为从命令行工具获取输出并解析它们的信息是垃圾。获取一个能够从 Java 查询 WMI 的库并使用它。

标签: java user-interface motherboard


【解决方案1】:

你应该使用另一种形式的 Runtime.exec :

        String[] command = {"wmic", "baseboard", "get", "serial number"};
        Process p = Runtime.getRuntime().exec(command);

【讨论】:

  • 通常当您调用带有参数的外部命令时,exec(String) 方法无法按预期工作。在这些情况下,exec(String[]) 版本更可靠。
【解决方案2】:

问题是你读到了multi-line 输出

while (true) {
    String line = inn.readLine();
    if (line == null) {
            break;
        }
...

但您始终只存储当前在文本字段中读取的行。表示先前的输出被覆盖。

...
        motherboard.setText(line);
}

由于输出的最后一行是 empty line,因此您的文本字段会显示此空行(意味着您看不到任何输出)。

编辑以下仅为完整性添加。

一个小方法,可以用作String serialNumber = getSerialNumber()。它过滤掉标题行和空行。

static String getSerialNumber() throws IOException, InterruptedException {
    ProcessBuilder pb = new ProcessBuilder("wmic", "baseboard", 
            "get", "serialnumber");
    Process process = pb.start();
    process.waitFor();
    String serialNumber = "";
    try (BufferedReader br = new BufferedReader(new InputStreamReader(
            process.getInputStream()))) {
        for (String line = br.readLine(); line != null; line = br.readLine()) {
            if (line.length() < 1 || line.startsWith("SerialNumber")) {
                continue;
            }
            serialNumber = line;
            break;
        }
    }
    return serialNumber;
}

另一种方法是在 wmic 命令上进行过滤,并且只读取输出的第一行。

使用 Windows 提供的命令行工具

wmic baseboard get serialnumber | findstr /r /v "^$" | findstr /v "SerialNumber"

或者使用自定义XSL来控制wmic的输出。

另存为simple.xsl

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text"/>
<xsl:template match="/"><xsl:apply-templates select="COMMAND/RESULTS"/>
</xsl:template>
</xsl:stylesheet>

然后运行命令

wmic baseboard get serialnumber /Format:.\simple

【讨论】:

    【解决方案3】:
     try
        {
            String result = null;
            Process p = Runtime.getRuntime().exec("wmic baseboard get serialnumber");
            BufferedReader input
                    = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String line;
            while ((line = input.readLine()) != null)
            {
                result += line;
            }
            if (result.equalsIgnoreCase(" ")) {
                System.out.println("Result is empty");
            } else
            {
                motherboard.setText(result);
            }
            input.close();
        } catch (IOException ex)
        {
            Exceptions.printStackTrace(ex);
        }
    

    【讨论】:

      【解决方案4】:
      private void serial(){
          // wmic command for diskdrive id: wmic DISKDRIVE GET SerialNumber
          // wmic command for cpu id : wmic cpu get ProcessorId
          Process process = null;
          try {
              process = Runtime.getRuntime().exec(new String[] { "wmic", "bios", "get", "SerialNumber" });
              //process = Runtime.getRuntime().exec(new String[] { "wmic", "DISKDRIVE", "get", "SerialNumber" });
             // process = Runtime.getRuntime().exec(new String[] { "wmic", "cpu", "get", "ProcessorId" });
             //process = Runtime.getRuntime().exec(new String[] { "wmic", "baseboard", "get", "SerialNumber" });
              process.getOutputStream().close();
          } catch (IOException ex) {
              Logger.getLogger(Activate.class.getName()).log(Level.SEVERE, null, ex);
          }
          Scanner sc = new Scanner(process.getInputStream());
          String property = sc.next();
          String serial = sc.next();
          System.out.println(property + ": " + serial);
          this.serial.setText(property + ": " + serial);
      }
      

      【讨论】:

      • 主板编号使用'baseboard'。
      • 能否请您解释一下为什么这是一个解决方案。
      • @IronMonkey 您可以使用 Scanner 类作为读取进程输入流的替代方法,而不是使用 BufferedReader。虽然我从未尝试过使用 BufferedReader,但 Scanner 为我完成了这项工作。
      【解决方案5】:
          getBufferReader("wmic logicaldisk get volumeserialnumber");
          getBufferReader("wmic csproduct get UUID");
          getBufferReader("wmic csproduct get name");
          getBufferReader("wmic CPU get ProcessorId");
          getBufferReader("wmic CPU get Architecture");
          getBufferReader("wmic CPU get NumberOfCores");
          getBufferReader("wmic CPU get ProcessorType");
          getBufferReader("wmic CPU get Revision");
          getBufferReader("wmic CPU get Family");
          getBufferReader("wmic CPU get Level");
          getBufferReader("wmic CPU get Name");
          getBufferReader("wmic CPU get SerialNumber");
          getBufferReader("wmic bios get Manufacturer");
          getBufferReader("wmic bios get Version");
          getBufferReader("wmic bios get SMBIOSBIOSVersion");
          getBufferReader("wmic bios get SMBIOSMajorVersion");
          getBufferReader("wmic bios get SMBIOSMinorVersion");
          getBufferReader("wmic bios get ReleaseDate");
          getBufferReader("wmic bios get serialnumber");
          getBufferReader("wmic baseboard get serialnumber");
          getBufferReader("wmic DISKDRIVE get SerialNumber");
          getBufferReader("wmic useraccount get name,sid");
      
      
          public static String getBufferReader(String getCode) throws IOException, Exception {
              StringBuilder output = new StringBuilder();
              Process processRun = Runtime.getRuntime().exec(getCode);
              BufferedReader processBuf = new BufferedReader(new InputStreamReader(processRun.getInputStream()));
              String line;
              while ((line = processBuf.readLine()) != null) {
                  output.append(line).append("\n");
              }
              return output.toString().substring(output.indexOf("\n"), output.length()).trim().replace("-", "");
          }
      

      【讨论】:

      • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
      猜你喜欢
      • 2011-01-30
      • 2017-09-14
      • 1970-01-01
      • 2011-04-06
      • 2011-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-06
      相关资源
      最近更新 更多