通过WMI获取计算机硬件信息

通过WMI获取计算机硬件信息

MSDN官网关于WMI的demo程序:https://docs.microsoft.com/zh-cn/windows/desktop/WmiSdk/example–getting-wmi-data-from-the-local-computer-asynchronously

MSDN官网关于WMI定义的所有类信息:https://msdn.microsoft.com/en-us/library/aa394084(VS.85).aspx

关于UUID:https://learn.microsoft.com/zh-tw/windows/win32/rpc/rpcdce/ns-rpcdce-uuid

https://www.cnblogs.com/tlduck/p/5132738.html
机器指纹获取:https://www.dandelioncloud.cn/article/details/1502236051971321857
最近由于项目的需要,需要在程序中获取机器的硬盘序列号和MAC地址等信息,在C#下,可以很容易的获得这些信息,但是在C++程序中感觉比较麻烦。经过百度,发现很多大虾都是通过WMI来获取这些硬件信息的,网上也有相关的代码,通过实际调试,也发现确实可以通过WMI来获取这些信息。前两天,在网上突然搜到一位大牛写的比较完整的程序,为了以后使用方便,就转载记录一下。同时,也会在大牛的代码中增加一些自己的注释,都是自己在实际使用过程中遇到的问题。

#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[] = {
// 网卡原生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"

"SELECT * FROM Win32_ComputerSystemProduct",
L"UUID"
}

std::string GetHardwareInfo::getDeviceFingerPrint() {
	//list<std::string>::iterator it;
	hash<std::string> str_hash;
	size_t num;
	char tmp[11] = { 0 };
	// 主板UUID存在,就使用主板UUID生成机器指纹
	//char thisUUID[128] = { 0 };
	//if (getUUID(thisUUID))
	//{
	//	std::string uuidstr = thisUUID;
	//	if (uuidstr.compare("FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF") != 0)
	//	{
	//		num = str_hash(uuidstr);
	//		sprintf(tmp, "%u", num);
	//		return string(tmp);
	//	}
	//}

	// 主板UUID不存在,使用CPUID、BIOS序列号生成机器指纹
	string otherStr("");
	char thisCPU_ID[128] = { 0 };
	if (getCPU_ID(thisCPU_ID))
	{
		otherStr.append(thisCPU_ID);
	}
	char thisBIOSSerialNumber[128] = { 0 };
	if (getBIOSSerialNumber(thisBIOSSerialNumber))
	{
		otherStr.append(thisBIOSSerialNumber);
	}
	//char thisBIOSSerialNumber[128] = { 0 };
	//if (getDevcieInfo((char*)"wmic diskdrive  get serialnumber", strList)) {
	//	string allDiskNum("");
	//	// 硬盘可能有多块
	//	for (it = strList.begin(); it != strList.end(); it++)
	//	{
	//		allDiskNum.append(*it);
	//	}
	//	//cout << allDiskNum ;
	//	//cout << str_hash(allDiskNum) << endl;
	//	otherStr.append(*strList.begin());
	//}
	//cout << str_hash(otherStr) << endl;
	//memset(tmp,0,11);
	num = str_hash(otherStr);
	sprintf(tmp, "%u", num);
	return string(tmp);
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值