如何標識一臺機器
在開發中,有時候我們需要獲取唯一標識本機的序列號,你可能會想到如下幾種
1) MAC地址
2) CPU ID
3) 硬碟ID
MAC地址
因為MAC地址可能會被修改,而且本機可能會有多張網絡卡,同時網絡卡的數量會隨著網絡卡被啟用或禁用而發生變化,所以暫時就不考慮使用MAC地址作為本機硬體標識了。
CPU ID
這個看起來不錯,但是有個問題:CPU廠商有時候為了規避隱私問題,會對同一批次的CPU打上同一個ID,這樣就不能透過CPU ID唯一的標識機器了。
硬碟ID
每一塊硬碟在出廠的時候,廠商會燒錄一個唯一的ID到硬碟中,這個標識通常可以獲取到,並且可以作為機器ID,但是在比較老的硬碟上可能沒有這個ID,另外在虛擬機器中,也可能是獲取不到硬碟ID的。哎,這種方法也是個問題。
綜合以上的描述,我建議使用多種方法聯合起來對機器進行標識,防止其中一個標識因無法獲取而無法最終實現硬體唯一性標識。
下面我們透過WMI的方法來獲取硬體序列號,這裡以CPU ID為例。
WMI
WMI(Windows Management Instrumentation,Windows 管理規範)是一項核心的 Windows 管理技術;使用者可以使用 WMI 管理本地和遠端計算機。
WMI初始化
在使用WMI進行WQL語句查詢之前,我們需要對WMI基礎設施進行初始化。一般包含如下幾個步驟:
1) COM庫初始化(CoInitializeEx)
2) COM庫安全機制初始化(CoInitializeSecurity)
3) 建立IWbemLocator介面例項(CoCreateInstance)
4) 連線至WMI服務(ConnectServer)
5) 設定請求代理的安全級別(CoSetProxyBlanket)
以下是具體程式碼片段
使用WQL進行查詢
WMI支援WQL語句查詢,這個WQL非常類似SQL,例如,查詢CPU資訊的語句如下:
SELECT * FROM win32_Processor
讀取CPU ID的步驟如下
1) 執行WQL查詢語句(ExecQuery)
此呼叫會建立一個IEnumWbemClassObject介面的列舉器例項,後面會用到這個列舉器
2) 列舉CPU個數(Next),返回一個IWbemClassObject物件代表當前CPU
3) 呼叫IWbemClassObject物件的Get方法獲取具體的屬性,例如CPU ID。
4) 釋放IWbemClassObject物件
5) 當列舉完畢,釋放IEnumWbemClassObject物件
具體程式碼片段如下:
WMI釋放
當不再使用WMI元件的時候,一定要記得釋放相關的介面例項,以及COM庫,避免資源洩漏。
總結
1) WMI的好處在於統一的介面和呼叫方式,作業系統直接在底層提供了支援,不需要我們深入到硬體層面去了解各種不同的硬體資訊。
2) 不好的地方:WMI呼叫,特別是初始化的時候,需要的時間比較長,這個對於效能敏感及要求快速獲取相關資訊的應用來說,需要慎重考慮。