轉: 經過WMI獲取網卡MAC地址、硬盤序列號、主板序列號、CPU ID、BIOS序列號 WMI教程-WMI查詢(WQL語言初步)

   最近因爲項目的須要,須要在程序中獲取機器的硬盤序列號和MAC地址等信息,在C#下,能夠很容易的得到這些信息,可是在C++程序中感受比較麻煩。通過百度,發現不少大蝦都是經過WMI來獲取這些硬件信息的,網上也有相關的代碼,經過實際調試,也發現確實能夠經過WMI來獲取這些信息。前兩天,在網上忽然搜到一位大牛寫的比較完整的程序,爲了之後使用方便,就轉載記錄一下。同時,也會在大牛的代碼中增長一些本身的註釋,都是本身在實際使用過程當中遇到的問題。html

//WMI教程-WMI查詢(WQL語言初步)

#include "stdafx.h" #define _WIN32_DCOM #include "stdafx.h" #include<iostream> #include<fstream> #include<string> #include "direct.h" #include <tchar.h> #include <time.h> #include <comdef.h> #include <Wbemidl.h> #include <conio.h> #include "atlstr.h" #include "atlbase.h" //#include "TcpCtl.h" //#include "winsock2.h" //#include "InitDll.h" using namespace std; # pragma comment(lib, "wbemuuid.lib") # pragma comment(lib, "ws2_32.lib") //經過WMI獲取主板號 BOOL ManageWMIBord(char bord[]) { HRESULT hres; // Step 1: 初始化COM //hres = CoInitializeEx(0, COINIT_MULTITHREADED); //網上的代碼都是使用這行語句進行初始化,可是我在實際使用中,發現也能夠採用下面的語句進行初始化 hres = CoInitialize(0); //網上的代碼是沒有註釋下面這個判斷的,可是實際使用中發現,若是以前已經初始化成功了,在第二次初始化的時候,下面的代碼就會致使返回false,因此,實際使用中我就註釋掉了 //if (FAILED(hres)) //{ // cout << "Failed to initialize COM library. Error code = 0x" // << hex << hres << endl; // return false; // Program has failed. //} // Step 2: 設置COM的安全認證級別 //在實際使用過程當中,我發現若是這一步不註釋掉的話,程序老是返回false,註釋掉以後程序反而能夠正常運行,緣由未知 // Note: If you are using Windows 2000, you need to specify - // the default authentication credentials for a user by using // a SOLE_AUTHENTICATION_LIST structure in the pAuthList ---- // parameter of CoInitializeSecurity ------------------------ ////hres = CoInitializeSecurity( //// NULL, //// -1, // COM authentication //// NULL, // Authentication services //// NULL, // Reserved //// RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication //// RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation //// NULL, // Authentication info //// EOAC_NONE, // Additional capabilities //// NULL // Reserved //// ); //// ////if (FAILED(hres)) ////{ //// cout << "Failed to initialize security. Error code = 0x" //// << hex << hres << endl; //// CoUninitialize(); //// return false; // Program has failed. ////} // Step 3: 得到WMI鏈接COM接口 IWbemLocator *pLoc = NULL; hres = CoCreateInstance( CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *)&pLoc); if (FAILED(hres)) { cout << "Failed to create IWbemLocator object." << " Err code = 0x" << hex << hres << endl; CoUninitialize(); return false; // Program has failed. } // Step 4: 經過鏈接接口鏈接WMI的內核對象名"ROOT//CIMV2" IWbemServices *pSvc = NULL; hres = pLoc->ConnectServer( _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace NULL, // User name. NULL = current user NULL, // User password. NULL = current 0, // Locale. NULL indicates current NULL, // Security flags. 0, // Authority (e.g. Kerberos) 0, // Context object &pSvc // pointer to IWbemServices proxy ); if (FAILED(hres)) { cout << "Could not connect. Error code = 0x" << hex << hres << endl; pLoc->Release(); CoUninitialize(); return false; // Program has failed. } //cout << "Connected to ROOT\\CIMV2 WMI namespace" << endl; // Step 5: 設置請求代理的安全級別 hres = CoSetProxyBlanket( pSvc, // Indicates the proxy to set RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx NULL, // Server principal name RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx NULL, // client identity EOAC_NONE // proxy capabilities ); if (FAILED(hres)) { cout << "Could not set proxy blanket. Error code = 0x" << hex << hres << endl; pSvc->Release(); pLoc->Release(); CoUninitialize(); return false; // Program has failed. } // Step 6: 經過請求代理來向WMI發送請求---- // For example, get the name of the operating system IEnumWbemClassObject* pEnumerator = NULL; hres = pSvc->ExecQuery( bstr_t("WQL"), //bstr_t("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = 'TRUE'"), bstr_t("SELECT * FROM Win32_BaseBoard"),//只須要經過修改這裏的查詢語句,就能夠實現對MAC地址等其餘信息的查詢 WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator); if (FAILED(hres)) { cout << "Query for Network Adapter Configuration failed." << " Error code = 0x" << hex << hres << endl; pSvc->Release(); pLoc->Release(); CoUninitialize(); return false; // Program has failed. } // Step 7: 循環枚舉全部的結果對象 IWbemClassObject *pclsObj; ULONG uReturn = 0; while (pEnumerator) { HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); if (0 == uReturn) { break; } VARIANT vtProp; VariantInit(&vtProp); hr = pclsObj->Get(L"SerialNumber", 0, &vtProp, 0, 0);//查詢不一樣的硬件信息,除了修改上面的查詢語句,這裏的字段也要修改 if (!FAILED(hr)) { CW2A tmpstr1(vtProp.bstrVal); strcpy_s(bord, 200, tmpstr1);//這裏的200是可調的,本身根據實際狀況設置,可是確定不能大於bord的長度 //cout << "BordSN:" << sn << endl; } VariantClear(&vtProp); }//end while // 釋放資源 pSvc->Release(); pLoc->Release(); pEnumerator->Release(); pclsObj->Release(); CoUninitialize(); return true; // Program successfully completed. } //附: WQL查詢語句 const T_WQL_QUERY szWQLQuery[] = {
   // 查詢有效IP地址 這句在WMI Explorer中會報錯,不知道爲何
   "select * from Win32_NetworkAdapterConfiguration WHERE (DefaultIPGateway IS NOT NULL)"
  
// 網卡原生MAC地址 "SELECT * FROM Win32_NetworkAdapter WHERE (MACAddress IS NOT NULL) AND (NOT (PNPDeviceID LIKE 'ROOT%'))", L"PNPDeviceID", // 硬盤序列號 "SELECT * FROM Win32_DiskDrive WHERE (SerialNumber IS NOT NULL) AND (MediaType LIKE 'Fixed hard disk%')", L"SerialNumber", // 主板序列號 "SELECT * FROM Win32_BaseBoard WHERE (SerialNumber IS NOT NULL)", L"SerialNumber", // 處理器ID "SELECT * FROM Win32_Processor WHERE (ProcessorId IS NOT NULL)", L"ProcessorId", // BIOS序列號 "SELECT * FROM Win32_BIOS WHERE (SerialNumber IS NOT NULL)", L"SerialNumber", // 主板型號 "SELECT * FROM Win32_BaseBoard WHERE (Product IS NOT NULL)", L"Product", // 網卡當前MAC地址 "SELECT * FROM Win32_NetworkAdapter WHERE (MACAddress IS NOT NULL) AND (NOT (PNPDeviceID LIKE 'ROOT%'))", L"MACAddress", //當前機器的型號和廠商 "SELECT * FROM Win32_computersystem", L"Manufacturer", L"Model" }
相關文章
相關標籤/搜索