如何在 GUI 上获取主板序列号(在 java 中)

Posted

技术标签:

【中文标题】如何在 GUI 上获取主板序列号(在 java 中)【英文标题】:how to get motherboard serial number on GUI (in 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!");
    

【问题讨论】:

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

以上是关于如何在 GUI 上获取主板序列号(在 java 中)的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Delphi 中获取主板 ID 或序列号?

如何获取设备的主板序列号

在 Linux 中获取主板设备 ID 和 BIOS 序列号

java如何获取系统内存、cpu等信息。

LINUX中,如何查看CPU,MEM,DISK,主板的相关信息?

批处理 命令获取主板序列号 硬盘序列号 CPU ID?