在軟體授權、裝置指紋、資產管理等場景,常需取得機器唯一識別碼。本文示範使用 System.Management 命名空間(WMI)查詢 Win32_NetworkAdapterConfiguration 取得啟用中網卡的 MAC 位址,以及 Win32_LogicalDisk 取得系統磁碟(通常為 C:)的磁碟區序號。
using System;
using System.Management;
using System.Linq;
namespace HardwareInfo
{
public static class DeviceIdentifier
{
///
/// 取得第一張啟用 IP 的網卡 MAC 位址(不含冒號)
///
public static string GetMacAddress()
{
try
{
using (var mc = new ManagementClass("Win32_NetworkAdapterConfiguration"))
using (var moc = mc.GetInstances())
{
foreach (ManagementObject mo in moc)
{
if ((bool)mo["IPEnabled"] == true)
{
string mac = mo["MacAddress"]?.ToString();
if (!string.IsNullOrWhiteSpace(mac))
return mac.Replace(":", "").Replace("-", "").ToUpperInvariant();
}
}
}
}
catch (ManagementException ex)
{
// 記錄日誌:WMI 查詢失敗
}
return string.Empty;
}
///
/// 取得指定磁碟機(預設 C:)的磁碟區序號
///
public static string GetVolumeSerialNumber(string driveLetter = "C")
{
try
{
string query = $"SELECT VolumeSerialNumber FROM Win32_LogicalDisk WHERE DeviceID = '{driveLetter}:'";
using (var searcher = new ManagementObjectSearcher(query))
using (var results = searcher.Get())
{
foreach (ManagementObject disk in results)
{
string serial = disk["VolumeSerialNumber"]?.ToString();
if (!string.IsNullOrWhiteSpace(serial))
return serial.ToUpperInvariant();
}
}
}
catch (ManagementException ex)
{
// 記錄日誌
}
return string.Empty;
}
}
}
ManagementObjectSearcher + WQL 條件篩選(WHERE DeviceID = 'C:'),避免枚舉所有磁碟再過濾。ManagementObject、ManagementClass、ManagementObjectCollection 皆實作 IDisposable,務必包在 using 區塊釋放非受控資源。00:1A:2B:3C:4D:5E 或 00-1A-2B-3C-4D-5E),統一移除並轉大寫便於比對。IPEnabled == true 的實體網卡,避開虛擬介面(Hyper-V、VPN、Loopback)。| 項目 | 磁碟區序號 (VolumeSerialNumber) | 硬碟實體序號 (SerialNumber) |
|---|---|---|
| 來源 | Win32_LogicalDisk | Win32_DiskDrive |
| 層級 | 邏輯分割區(格式化時產生) | 實體裝置(出廠燒錄) |
| 重裝系統後 | 改變 | 不變 |
| 適用場景 | 簡易授權綁定、快速指紋 | 嚴格裝置綁定、防盜版 |
注意:本範例取得的是磁碟區序號,重新格式化或重裝系統會改變。若需更穩定的硬體 ID,請改查 Win32_DiskDrive.SerialNumber 或 Win32_BaseBoard.SerialNumber(主機板)。
ManagementException: Invalid namespace?winmgmt 服務正在執行,或嘗試 mofcomp.exe 重新註冊。Description 含 "Virtual"、"VPN"、"Hyper-V" 的介面。runAsAdministrator 或使用服務帳號。System.Management(Windows 專用),並確認專案目標框架包含 net6.0-windows 等 Windows 專用 TFM。public static string GenerateDeviceFingerprint()
{
string mac = GetMacAddress();
string vol = GetVolumeSerialNumber("C");
string cpuId = GetCpuId(); // 需另行實作 Win32_Processor.ProcessorId
string raw = $"{mac}|{vol}|{cpuId}";
using (var sha256 = System.Security.Cryptography.SHA256.Create())
{
byte[] hash = sha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(raw));
return Convert.ToHexString(hash).Substring(0, 32); // 取前 32 字元
}
}
透過 WMI 取得 MAC 位址與磁碟區序號是 Windows 平台常見的硬體識別手法。掌握 WQL 查詢、資源釋放、權限需求與虛擬環境干擾等細節,才能在實務專案中穩定運作。若需更高安全性,建議結合 TPM、安全啟動或雲端驗證機制。