首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 使用 WMI 取得 MAC 位址、CPU 序號、硬碟序號等硬體資訊

     編輯:關於C#

核心命名空間

System.Management 提供 ManagementObjectSearcher 查詢 WMI 類別:

  • Win32_NetworkAdapterConfiguration → MAC 位址 (僅 IPEnabled=true 的實體網卡)
  • Win32_Processor → ProcessorId (CPU 序號)
  • Win32_DiskDrive → SerialNumber (硬碟序號),Model (型號)
  • Win32_BaseBoard → SerialNumber (主機板序號)
  • Win32_BIOS → SerialNumber (BIOS 序號)

完整工具類別

using System;
using System.Management;
using System.Text;

public static class HardwareInfo
{
    /// 取得第一張啟用 IP 的網卡 MAC 位址 (不含分隔符)
    public static string GetMacAddress()
    {
        using var mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
        foreach (ManagementObject mo in mc.GetInstances())
        {
            if ((bool)mo["IPEnabled"])
            {
                string mac = mo["MacAddress"]?.ToString().Replace(":", "").Replace("-", "");
                if (!string.IsNullOrEmpty(mac)) return mac;
            }
        }
        return string.Empty;
    }

    /// 取得 CPU 序號 (ProcessorId)
    public static string GetCpuId()
    {
        using var mc = new ManagementClass("Win32_Processor");
        foreach (ManagementObject mo in mc.GetInstances())
        {
            string id = mo["ProcessorId"]?.ToString().Trim();
            if (!string.IsNullOrEmpty(id)) return id;
        }
        return string.Empty;
    }

    /// 取得第一顆實體硬碟序號
    public static string GetDiskSerial()
    {
        using var searcher = new ManagementObjectSearcher("SELECT SerialNumber FROM Win32_DiskDrive WHERE MediaType LIKE '%Fixed%'");
        foreach (ManagementObject mo in searcher.Get())
        {
            string sn = mo["SerialNumber"]?.ToString().Trim();
            if (!string.IsNullOrEmpty(sn)) return sn;
        }
        return string.Empty;
    }

    /// 取得主機板序號
    public static string GetBoardSerial()
    {
        using var searcher = new ManagementObjectSearcher("SELECT SerialNumber FROM Win32_BaseBoard");
        foreach (ManagementObject mo in searcher.Get())
        {
            string sn = mo["SerialNumber"]?.ToString().Trim();
            if (!string.IsNullOrEmpty(sn)) return sn;
        }
        return string.Empty;
    }

    /// 一次取得所有關鍵硬體 ID,適合授權綁定
    public static string GetCompositeHardwareId()
    {
        var sb = new StringBuilder();
        sb.Append("CPU:").Append(GetCpuId()).Append('|');
        sb.Append("MAC:").Append(GetMacAddress()).Append('|');
        sb.Append("DISK:").Append(GetDiskSerial()).Append('|');
        sb.Append("BOARD:").Append(GetBoardSerial());
        return sb.ToString();
    }
}

使用範例

Console.WriteLine("MAC:    " + HardwareInfo.GetMacAddress());
Console.WriteLine("CPU ID: " + HardwareInfo.GetCpuId());
Console.WriteLine("Disk SN:" + HardwareInfo.GetDiskSerial());
Console.WriteLine("Board SN:" + HardwareInfo.GetBoardSerial());
Console.WriteLine("Composite ID: " + HardwareInfo.GetCompositeHardwareId());

權限與部署注意事項

執行權限目標平台參考組件虛擬機/容器效能
項目說明
需系統管理員權限 (UAC 提權),否則部分 WMI 查詢回傳空值或拋出 Access Denied。
專案屬性 → Build → 取消勾選 Prefer 32-bit (Any CPU 64-bit),確保在 64 位元 OS 正確載入 WMI 提供者。
專案需參考 System.Management.dll (.NET Framework 內建;.NET Core/.NET 5+ 需 NuGet 安裝 System.Management 套件)。
VM 的 CPU ID、MAC、磁碟序號可能隨遷移、快照、複製而改變,不適合作為永久授權綁定依據。
WMI 查詢較慢 (數百毫秒至秒級),建議啟動時快取,避免重複查詢。

替代方案:不依賴 WMI

  • NetworkInterface.GetAllNetworkInterfaces() (System.Net.NetworkInformation) → 取得 MAC,速度較快、無需管理員權限。
  • System.Management.Automation (PowerShell SDK) → 執行 Get-CimInstance,效能優於傳統 WMI。
  • P/Invoke GetVolumeInformation → 取得邏輯磁碟區序號 (非實體硬碟序號),但無需 WMI。

總結

透過 System.Management 查詢標準 WMI 類別,可可靠取得 MAC、CPU ID、硬碟/主機板序號等硬體識別資訊,適用於軟體授權綁定、資產管理、裝置指紋等場景,唯需注意權限、平台與虛擬化環境的限制。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved