C获取BIOS信息 Windows_win32


C++获取计算机硬件信息(Windows)


C++获取计算机硬件信息(Linux)

“流水下山非有意, 片云归洞本无心;人生若得如云水, 铁树开花遍界春。”


获取计算机硬件信息:

  • 1、获取屏幕分辨率
  • 1.1 GetSystemMetrics
  • 1.2 GetDeviceCaps
  • 1.3 SystemParametersInfo
  • 1.4 GetDesktopWindow
  • 2、获取屏幕显示比例
  • 3、获取计算机名
  • 3.1 GetComputerName
  • 3.2 gethostname
  • 4、获取计算机登录用户名
  • 5、获取计算机的IP地址
  • 5.1 gethostbyname
  • 6、获取操作系统版本
  • 7、获取内存信息
  • 8、获取显卡GPU信息
  • 9、获取处理器CPU信息
  • 9.1 注册表方式
  • 9.2 cpuid指令方式
  • 9.3 WMI方式
  • 10、获取硬盘容量信息
  • 结语


1、获取屏幕分辨率

C获取BIOS信息 Windows_c++_02

1.1 GetSystemMetrics

https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsystemmetrics

  • 整个屏幕区域。
#include <iostream>
#include <windows.h>

int main()
{
	int cx = GetSystemMetrics(SM_CXSCREEN);
	int cy = GetSystemMetrics(SM_CYSCREEN);

	std::cout << "宽:" << cx << ", 高:" << cy << std::endl;
}

以上代码运行结果:
宽:1536, 高:864

  • 不包括任务栏等区域.
#include <iostream>
#include <windows.h>

int main()
{
	int cx = GetSystemMetrics(SM_CXFULLSCREEN);
	int cy = GetSystemMetrics(SM_CYFULLSCREEN);

	std::cout << "宽:" << cx << ", 高:" << cy << std::endl;
}

以上代码运行结果:
宽:1536, 高:801

1.2 GetDeviceCaps

https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-getdevicecaps

int main()
{
	HDC hDC = ::GetDC(NULL);             
	int cx = ::GetDeviceCaps(hDC, HORZRES);     
	int cy = ::GetDeviceCaps(hDC, VERTRES);     
	::ReleaseDC(NULL, hDC);                 

	std::cout << "宽:" << cx << ", 高:" << cy << std::endl;
}

以上代码运行结果:
宽:1536, 高:864

#include <iostream>
#include <windows.h>

int main()
{
	HDC hDC = ::GetDC(NULL);
	int cx = ::GetDeviceCaps(hDC, DESKTOPHORZRES);
	int cy = ::GetDeviceCaps(hDC, DESKTOPVERTRES);
	::ReleaseDC(NULL, hDC);

	std::cout << "宽:" << cx << ", 高:" << cy << std::endl;
}

以上代码运行结果:
宽:1920, 高:1080

1.3 SystemParametersInfo

https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-systemparametersinfoa

#include <iostream>
#include <windows.h>

int main()
{
	RECT rect;
	SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, SPIF_SENDCHANGE);
	int cx = (rect.right - rect.left);
	int cy = (rect.bottom - rect.top);

	std::cout << "宽:" << cx << ", 高:" << cy << std::endl;
}

以上代码运行结果:
宽:1536, 高:824

1.4 GetDesktopWindow

https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdesktopwindow

#include <iostream>
#include <windows.h>

int main()
{
	HWND hd = GetDesktopWindow();
	RECT rect;
	GetWindowRect(hd, &rect);
	int cx = (rect.right - rect.left);
	int cy = (rect.bottom - rect.top);

	std::cout << "宽:" << cx << ", 高:" << cy << std::endl;
}

以上代码运行结果:
宽:1536, 高:864

2、获取屏幕显示比例

DPI 值

缩放百分比

96

100%

120

125%

144

150%

192

200%

#include <Windows.h>
#include <iostream>

HWND hd = GetDesktopWindow();
int zoom = GetDpiForWindow(hd);
double dpi = 0;

switch (zoom) {
case 96:
	dpi = 1;
	std::cout << "100%" << std::endl;
	break;
case 120:
	dpi = 1.25;
	std::cout << "125%" << std::endl;
	break;
case 144:
	dpi = 1.5;
	std::cout << "150%" << std::endl;
	break;
case 192:
	dpi = 2;
	std::cout << "200%" << std::endl;
	break;
default:
	std::cout << "error" << std::endl;
	break;
}
auto dc = GetDC(nullptr);
auto x = GetDeviceCaps(dc, LOGPIXELSX);
auto y = GetDeviceCaps(dc, LOGPIXELSY);
ReleaseDC(nullptr, dc);

3、获取计算机名

C获取BIOS信息 Windows_win32_03

3.1 GetComputerName

https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getcomputernamea

BOOL GetComputerNameA(
  [out]     LPSTR   lpBuffer,
  [in, out] LPDWORD nSize
);
BOOL GetComputerNameW(
  [out]     LPWSTR  lpBuffer,
  [in, out] LPDWORD nSize
);
#include <tchar.h>
#include <stdio.h>

#define INFO_BUFFER_SIZE 32767
TCHAR  infoBuf[INFO_BUFFER_SIZE];
DWORD  bufCharCount = INFO_BUFFER_SIZE;

GetComputerName( infoBuf, &bufCharCount );
_tprintf( TEXT("\nComputer name:      %s"), infoBuf );

3.2 gethostname

https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-gethostname

int gethostname(
  [out] char *name,
  [in]  int  namelen
);
#include <iostream>
#include "winsock2.h"
#pragma comment(lib,"ws2_32.lib")

void main()
{
	WSAData data;
	if (WSAStartup(MAKEWORD(1, 1), &data) != 0) {
		std::cout << "WSAStartup初始化失败!" << std::endl;
		return;
	}

	char host[255];
	if (gethostname(host, sizeof(host)) == SOCKET_ERROR) {
		std::cout << "无法获取主机名..." << std::endl;
	}
	else {
		std::cout << "本机计算机名为:" << host << std::endl;
	}
	
	WSACleanup();
	system("pause");
}

4、获取计算机登录用户名

https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getusernamea

BOOL GetUserNameA(
  [out]     LPSTR   lpBuffer,
  [in, out] LPDWORD pcbBuffer
);
BOOL GetUserNameW(
  [out]     LPWSTR  lpBuffer,
  [in, out] LPDWORD pcbBuffer
);
#include <tchar.h>
#include <stdio.h>

#define INFO_BUFFER_SIZE 32767
TCHAR  infoBuf[INFO_BUFFER_SIZE];
DWORD  bufCharCount = INFO_BUFFER_SIZE;

GetUserName( infoBuf, &bufCharCount ) ;
 _tprintf( TEXT("\nUser name:          %s"), infoBuf );

5、获取计算机的IP地址

C获取BIOS信息 Windows_c++_04

5.1 gethostbyname

https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-gethostbyname

hostent *WSAAPI gethostbyname(
  const char *name
);
#include <iostream>
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib")

void main()
{
	WSAData data;
	if (WSAStartup(MAKEWORD(2, 2), &data) != 0) {
		std::cout << "WSAStartup初始化失败!" << std::endl;
		return;
	}
	
	struct hostent *p = gethostbyname(NULL);
	if (p == NULL) {
		std::cout << "无法获取计算机主机名及IP..." << std::endl;
	}
	else {
		std::cout<<"本机计算机名为:"<<p->h_name<< std::endl;
		
		for (int i = 0; p->h_addr_list[i] != 0; i++) {
			struct in_addr in;
			memcpy(&in, p->h_addr_list[i], sizeof(struct in_addr));
			std::cout << "第" << i + 1 << "块网卡的IP为:" << inet_ntoa(in) << std::endl;
		}

	}

	WSACleanup();
	system("pause");
}

6、获取操作系统版本

Operating system

Version number

Windows 11

10.0*

Windows 10

10.0*

Windows Server 2022

10.0*

Windows Server 2019

10.0*

Windows Server 2016

10.0*

Windows 8.1

6.3*

Windows Server 2012 R2

6.3*

Windows 8

6.2

Windows Server 2012

6.2

Windows 7

6.1

Windows Server 2008 R2

6.1

Windows Server 2008

6.0

Windows Vista

6.0

Windows Server 2003 R2

5.2

Windows Server 2003

5.2

Windows XP 64-Bit Edition

5.2

Windows XP

5.1

Windows 2000

5.0

C获取BIOS信息 Windows_C获取BIOS信息 Windows_05

https://docs.microsoft.com/zh-cn/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsysteminfo

typedef struct _SYSTEM_INFO {
  union {
    DWORD dwOemId;
    struct {
      WORD wProcessorArchitecture;
      WORD wReserved;
    } DUMMYSTRUCTNAME;
  } DUMMYUNIONNAME;
  DWORD     dwPageSize;
  LPVOID    lpMinimumApplicationAddress;
  LPVOID    lpMaximumApplicationAddress;
  DWORD_PTR dwActiveProcessorMask;
  DWORD     dwNumberOfProcessors;
  DWORD     dwProcessorType;
  DWORD     dwAllocationGranularity;
  WORD      wProcessorLevel;
  WORD      wProcessorRevision;
} SYSTEM_INFO, *LPSYSTEM_INFO;
void GetSystemInfo(
  [out] LPSYSTEM_INFO lpSystemInfo
);
#include <iostream>
#include <Windows.h>

#pragma warning(disable : 4996)

BOOL Is_Win_Server()
{
	OSVERSIONINFOEX osvi;
	DWORDLONG dwlConditionMask = 0;
	int op = VER_GREATER_EQUAL;

	// Initialize the OSVERSIONINFOEX structure.

	ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
	osvi.dwMajorVersion = 5;
	osvi.dwMinorVersion = 0;
	osvi.wServicePackMajor = 0;
	osvi.wServicePackMinor = 0;
	osvi.wProductType = VER_NT_SERVER;

	// Initialize the condition mask.

	VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, op);
	VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, op);
	VER_SET_CONDITION(dwlConditionMask, VER_SERVICEPACKMAJOR, op);
	VER_SET_CONDITION(dwlConditionMask, VER_SERVICEPACKMINOR, op);
	VER_SET_CONDITION(dwlConditionMask, VER_PRODUCT_TYPE, VER_EQUAL);

	// Perform the test.

	return VerifyVersionInfo(
		&osvi,
		VER_MAJORVERSION | VER_MINORVERSION |
		VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR |
		VER_PRODUCT_TYPE,
		dwlConditionMask);
}

BOOL GetOSVersionName(char* versionName, size_t versionNameCapacity)
{
	const char* name = "unknown";

	/*------------------------*/
	//OS>=win8.1
	BOOL bWin81Over = FALSE;
	char processor[16];
	typedef void(__stdcall * NTPROC)(DWORD*, DWORD*, DWORD*);
	HINSTANCE hinst = LoadLibrary("ntdll.dll");
	DWORD dwMajor, dwMinor, dwBuildNumber;
	NTPROC proc = (NTPROC)GetProcAddress(hinst, "RtlGetNtVersionNumbers");
	if (proc) proc(&dwMajor, &dwMinor, &dwBuildNumber);

	if (dwMajor == 6 && dwMinor == 3) {
		if (Is_Win_Server())
			name = "Windows Server 2012 R2";
		else
			name = "Windows 8.1";
		bWin81Over = TRUE;
	}
	else if (dwMajor == 10 && dwMinor == 0) {
		if (Is_Win_Server())
			name = "Windows Server 2016";
		else
			name = "Windows 10";
		bWin81Over = TRUE;
	}

	if (bWin81Over) {
		sprintf_s(versionName, versionNameCapacity, "%s", name);
		return TRUE;
	}

	/*------------------------*/
	//OS<win8.1
	OSVERSIONINFOEX osvi;
	BOOL bOsVersionInfoEx;
	ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));

	// Try calling GetVersionEx using the OSVERSIONINFOEX structure.
	// If that fails, try using the OSVERSIONINFO structure.

	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
	if (!(bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO *)&osvi)))
	{
		osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
		if (!GetVersionEx((OSVERSIONINFO *)&osvi))
			return FALSE;
	}

	/*------------------------*/
	// Call GetNativeSystemInfo if supported
	// or GetSystemInfo otherwise.
	typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
	SYSTEM_INFO si;
	ZeroMemory(&si, sizeof(SYSTEM_INFO));
	PGNSI pGNSI = (PGNSI)GetProcAddress(
		GetModuleHandle(TEXT("kernel32.dll")),
		"GetNativeSystemInfo");
	if (NULL != pGNSI) pGNSI(&si);
	else GetSystemInfo(&si);

	switch (si.wProcessorArchitecture)
	{
	case PROCESSOR_ARCHITECTURE_AMD64:
		strcpy_s(processor, "x64");
		break;
	case PROCESSOR_ARCHITECTURE_IA64:
		strcpy_s(processor, "IA64");
		break;
	default:
		strcpy_s(processor, "x86");
		break;
	}

	/*------------------------*/
	if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
		if (osvi.dwMajorVersion >= 7) {
			// Unknown recent version.
		}
		else if (osvi.dwMajorVersion >= 6) {
			if (osvi.dwMinorVersion >= 4)
				name = "Windows 10";
			else if (osvi.dwMinorVersion >= 3) {
				if (osvi.wProductType == VER_NT_WORKSTATION)
					name = "Windows 8.1";
				else
					name = "Windows Server 2012 R2";
			}
			else if (osvi.dwMinorVersion >= 2) {
				if (osvi.wProductType == VER_NT_WORKSTATION)
					name = "Windows 8";
				else
					name = "Windows Server 2012";
			}
			else if (osvi.dwMinorVersion >= 1) {
				if (osvi.wProductType == VER_NT_WORKSTATION)
					name = "Windows 7";
				else
					name = "Windows Server 2008 R2";
			}
			else {
				if (osvi.wProductType == VER_NT_WORKSTATION)
					name = "Windows Vista";
				else
					name = "Windows Server 2008";
			}
		}
		else if (osvi.dwMajorVersion >= 5) {
			if (osvi.dwMinorVersion == 0)
				name = "Windows 2000";
			else if (osvi.dwMinorVersion == 1)
				name = "Windows XP";
			else if (osvi.dwMinorVersion == 2) {
				if (osvi.wProductType == VER_NT_WORKSTATION &&
					si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
					name = "Windows XP Professional x64 Edition";
				else if (GetSystemMetrics(SM_SERVERR2) != 0)  //2==GetSystemMetrics(/*SM_SERVERR2*/89)
					name = "Windows Server 2003 R2";
				else if (osvi.wSuiteMask/* & VER_SUITE_WH_SERVER*/)
					name = "Windows Home Server";

				if (GetSystemMetrics(SM_SERVERR2) == 0)
					name = "Windows Server 2003";
			}
		}
		else if (osvi.dwMajorVersion == 4) {
			if (osvi.dwMinorVersion == 0) {
				if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
					name = "Windows NT 4.0"; //1996
				else if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
					name = "Windows 95";
			}
			else if (osvi.dwMinorVersion == 10)
				name = "Windows 98";
			else if (osvi.dwMinorVersion == 90)
				name = "Windows Me";
		}
		else
			name = "Windows earlier";
	}

	if (osvi.wServicePackMajor != 0) {
		sprintf_s(versionName, versionNameCapacity, "%s SP%d(%s)", name, osvi.wServicePackMajor, processor);
	}
	else {
		sprintf_s(versionName, versionNameCapacity, "%s (%s)", name, processor);
	}

	return TRUE;
}

int main()
{
	char szOSVer[64];
	GetOSVersionName(szOSVer, 64);
	printf(szOSVer);

	return 0;
}

7、获取内存信息

C获取BIOS信息 Windows_win32_06


https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-globalmemorystatusex

BOOL GlobalMemoryStatusEx(
  [in, out] LPMEMORYSTATUSEX lpBuffer
);
typedef struct _MEMORYSTATUSEX {
  DWORD     dwLength;
  DWORD     dwMemoryLoad;
  DWORDLONG ullTotalPhys;
  DWORDLONG ullAvailPhys;
  DWORDLONG ullTotalPageFile;
  DWORDLONG ullAvailPageFile;
  DWORDLONG ullTotalVirtual;
  DWORDLONG ullAvailVirtual;
  DWORDLONG ullAvailExtendedVirtual;
} MEMORYSTATUSEX, *LPMEMORYSTATUSEX;
#include <windows.h>
#include <stdio.h>
#include <tchar.h>

#define DIV 1024
#define WIDTH 7

void main()
{
	MEMORYSTATUSEX statex;

	statex.dwLength = sizeof(statex);

	GlobalMemoryStatusEx(&statex);

	_tprintf(TEXT("There is  %*ld %% of memory in use.\n"),
		WIDTH, statex.dwMemoryLoad);
	_tprintf(TEXT("There are %*I64d total MB of physical memory.\n"),
		WIDTH, statex.ullTotalPhys / DIV / DIV );
	_tprintf(TEXT("There are %*I64d free  MB of physical memory.\n"),
		WIDTH, statex.ullAvailPhys / DIV / DIV);
	_tprintf(TEXT("There are %*I64d total MB of paging file.\n"),
		WIDTH, statex.ullTotalPageFile / DIV / DIV);
	_tprintf(TEXT("There are %*I64d free  MB of paging file.\n"),
		WIDTH, statex.ullAvailPageFile / DIV / DIV);
	_tprintf(TEXT("There are %*I64d total MB of virtual memory.\n"),
		WIDTH, statex.ullTotalVirtual / DIV / DIV);
	_tprintf(TEXT("There are %*I64d free  MB of virtual memory.\n"),
		WIDTH, statex.ullAvailVirtual / DIV / DIV);

	// Show the amount of extended memory available.

	_tprintf(TEXT("There are %*I64d free  MB of extended memory.\n"),
		WIDTH, statex.ullAvailExtendedVirtual / DIV / DIV);

	system("pause");
}

运行结果:

C获取BIOS信息 Windows_C获取BIOS信息 Windows_07

8、获取显卡GPU信息

#include <Windows.h>
#include <iostream>
#include <vector>
#include <DXGI.h>
#pragma comment(lib, "DXGI.lib")

void getGPU() {
	// 定义参数 
	IDXGIFactory * pFactory;
	IDXGIAdapter * pAdapter;
	std::vector <IDXGIAdapter*> vAdapters; 
	int iAdapterNum = 0;
	
	// 创建一个DXGI工厂  
	HRESULT hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)(&pFactory));

	if (FAILED(hr))
		return;

	// 枚举适配器  
	while (pFactory->EnumAdapters(iAdapterNum, &pAdapter) != DXGI_ERROR_NOT_FOUND)
	{
		vAdapters.push_back(pAdapter);
		++iAdapterNum;
	}

	// 输出显卡信息   
	std::cout << "====== 获取到" << iAdapterNum << "块显卡" << std::endl << std::endl;
	for (size_t i = 0; i < vAdapters.size(); i++)
	{
		//std::cout << "Video card" << i + 1 << ":" << std::endl;
		// 获取信息  
		DXGI_ADAPTER_DESC adapterDesc;
		vAdapters[i]->GetDesc(&adapterDesc);
		std::wstring aa(adapterDesc.Description);
		std::string bb = WStringToString(aa);
		std::cout << "Video card " << i + 1 << " DedicatedVideoMemory:" << adapterDesc.DedicatedVideoMemory / 1024 / 1024 << "M" << std::endl;
		std::cout << "Video card " << i + 1 << " SharedSystemMemory:" << adapterDesc.SharedSystemMemory / 1024 / 1024 << "M" << std::endl;
		// 输出显卡信息  
		//std::cout << "系统视频内存:" << adapterDesc.DedicatedSystemMemory / 1024 / 1024 << "M" << std::endl;
		//std::cout << "专用视频内存:" << adapterDesc.DedicatedVideoMemory / 1024 / 1024 << "M" << std::endl;
		//std::cout << "共享系统内存:" << adapterDesc.SharedSystemMemory / 1024 / 1024 << "M" << std::endl;
		std::cout << "设备描述:" << bb.c_str() << std::endl;
		//std::cout << "设备ID:" << adapterDesc.DeviceId << std::endl;
		//std::cout << "PCI ID修正版本:" << adapterDesc.Revision << std::endl;
		//std::cout << "子系统PIC ID:" << adapterDesc.SubSysId << std::endl;
		//std::cout << "厂商编号:" << adapterDesc.VendorId << std::endl;

		// 输出设备  
		IDXGIOutput * pOutput;
		std::vector<IDXGIOutput*> vOutputs;
		// 输出设备数量  
		int iOutputNum = 0;
		while (vAdapters[i]->EnumOutputs(iOutputNum, &pOutput) != DXGI_ERROR_NOT_FOUND)
		{
			vOutputs.push_back(pOutput);
			iOutputNum++;
		}

		for (size_t n = 0; n < vOutputs.size(); n++)
		{
			// 获取显示设备信息  
			DXGI_OUTPUT_DESC outputDesc;
			vOutputs[n]->GetDesc(&outputDesc);

			// 获取设备支持  
			UINT uModeNum = 0;
			DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM;
			UINT flags = DXGI_ENUM_MODES_INTERLACED;

			vOutputs[n]->GetDisplayModeList(format, flags, &uModeNum, 0);
			DXGI_MODE_DESC * pModeDescs = new DXGI_MODE_DESC[uModeNum];
			vOutputs[n]->GetDisplayModeList(format, flags, &uModeNum, pModeDescs);

			//std::cout << "DisplayDevice:" << n + 1 << " Name:" << outputDesc.DeviceName << std::endl;
			std::cout << "DisplayDevice " << n + 1 << " Resolution ratio:" << outputDesc.DesktopCoordinates.right - outputDesc.DesktopCoordinates.left << "*" << outputDesc.DesktopCoordinates.bottom - outputDesc.DesktopCoordinates.top << std::endl;

			// 所支持的分辨率信息  
			//std::cout << "分辨率信息:" << std::endl;
			/*for (UINT m = 0; m < uModeNum; m++)
			{
				std::cout << "== 分辨率:" << pModeDescs[m].Width << "*" << pModeDescs[m].Height << "     刷新率" << (pModeDescs[m].RefreshRate.Numerator) / (pModeDescs[m].RefreshRate.Denominator) << std::endl;
			}*/
		}
		vOutputs.clear();
		std::cout << std::endl;
	}
	vAdapters.clear();
}

9、获取处理器CPU信息

9.1 注册表方式

//64位操作系统上需要通过管理员权限运行,才能获取正确结果
#include <Windows.h>
#include <iostream>
#include <atlbase.h>

void GetCpuInfo(std::string &chProcessorName, std::string &chProcessorType, DWORD &dwNum, DWORD &dwMaxClockSpeed)
{
	std::string strPath = "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0";
	CRegKey regkey;
	LONG lResult;
	lResult = regkey.Open(HKEY_LOCAL_MACHINE, strPath.c_str(), KEY_ALL_ACCESS);
	if (lResult != ERROR_SUCCESS)
	{
		return;
	}

	char chCPUName[50] = { 0 };
	DWORD dwSize = 50;
	//获取ProcessorNameString字段值  
	if (ERROR_SUCCESS == regkey.QueryStringValue(_T("ProcessorNameString"), chCPUName, &dwSize))
	{
		chProcessorName = chCPUName;
	}

	//查询CPU主频  
	DWORD dwValue;
	if (ERROR_SUCCESS == regkey.QueryDWORDValue(_T("~MHz"), dwValue))
	{
		dwMaxClockSpeed = dwValue;
	}
	regkey.Close();

	//获取CPU核心数目  
	SYSTEM_INFO si;
	memset(&si, 0, sizeof(SYSTEM_INFO));
	GetSystemInfo(&si);
	dwNum = si.dwNumberOfProcessors;

	switch (si.dwProcessorType)
	{
	case PROCESSOR_INTEL_386:
		chProcessorType="Intel 386 processor";
		break;
	case PROCESSOR_INTEL_486:
		chProcessorType="Intel 486 Processor";
		break;
	case PROCESSOR_INTEL_PENTIUM:
		chProcessorType="Intel Pentium Processor";
		break;
	case PROCESSOR_INTEL_IA64:
		chProcessorType="Intel IA64 Processor";
		break;
	case PROCESSOR_AMD_X8664:
		chProcessorType="AMD X8664 Processor";
		break;
	default:
		chProcessorType="Unknown";
		break;
	}
}

9.2 cpuid指令方式

#ifdef _WIN64

// method 2: usde winapi, works for x86 and x64
#include <intrin.h>

/*CPU*/
void getCpuInfo()
{
	int cpuInfo[4] = { -1 };
	char cpu_manufacture[32] = { 0 };
	char cpu_type[32] = { 0 };
	char cpu_freq[32] = { 0 };

	__cpuid(cpuInfo, 0x80000002);
	memcpy(cpu_manufacture, cpuInfo, sizeof(cpuInfo));

	__cpuid(cpuInfo, 0x80000003);
	memcpy(cpu_type, cpuInfo, sizeof(cpuInfo));

	__cpuid(cpuInfo, 0x80000004);
	memcpy(cpu_freq, cpuInfo, sizeof(cpuInfo));

	//std::cout << "CPU manufacture: " << cpu_manufacture << std::endl;
	//std::cout << "CPU type: " << cpu_type << std::endl;
	//std::cout << "CPU main frequency: " << cpu_freq << std::endl;
	std::cout << "CPU:" << cpu_manufacture << cpu_type << cpu_freq << std::endl;
}

#else

// mothed 1: this kind asm embedded in code only works in x86 build
// save 4 register variables
DWORD deax;
DWORD debx;
DWORD decx;
DWORD dedx;

// init cpu in assembly language
void initCpu(DWORD veax)
{
	__asm
	{
		mov eax, veax
		cpuid
		mov deax, eax
		mov debx, ebx
		mov decx, ecx
		mov dedx, edx
	}
}

long getCpuFreq()
{
	int start, over;
	_asm
	{
		RDTSC
		mov start, eax
	}
	Sleep(50);
	_asm
	{
		RDTSC
		mov over, eax
	}
	return (over - start) / 50000;
}

std::string getManufactureID()
{
	char manuID[25];
	memset(manuID, 0, sizeof(manuID));

	initCpu(0);
	memcpy(manuID + 0, &debx, 4); // copy to array
	memcpy(manuID + 4, &dedx, 4);
	memcpy(manuID + 8, &decx, 4);

	return manuID;
}

std::string getCpuType()
{
	const DWORD id = 0x80000002; // start 0x80000002 end to 0x80000004
	char cpuType[49];
	memset(cpuType, 0, sizeof(cpuType));

	for (DWORD t = 0; t < 3; t++)
	{
		initCpu(id + t);

		memcpy(cpuType + 16 * t + 0, &deax, 4);
		memcpy(cpuType + 16 * t + 4, &debx, 4);
		memcpy(cpuType + 16 * t + 8, &decx, 4);
		memcpy(cpuType + 16 * t + 12, &dedx, 4);
	}

	return cpuType;
}

void getCpuInfo()
{
	//std::cout << "CPU manufacture: " << getManufactureID() << std::endl;
	//std::cout << "CPU type: " << getCpuType() << std::endl;
	//std::cout << "CPU main frequency: " << getCpuFreq() << "MHz" << std::endl;
	std::cout << "CPU :" << getManufactureID() << getCpuType() << getCpuFreq() << std::endl;
}

#endif

9.3 WMI方式

WMI方式可能需要管理员权限运行。

#include <Windows.h>
#define _WIN32_DCOM
#include <iostream>
using namespace std;
#include <comdef.h>
#include <Wbemidl.h>

#pragma comment(lib, "wbemuuid.lib")

int main(int argc, char **argv)
{
	HRESULT hres;

	// Step 1: --------------------------------------------------
	// Initialize COM. ------------------------------------------

	hres = CoInitializeEx(0, COINIT_MULTITHREADED);
	if (FAILED(hres))
	{
		cout << "Failed to initialize COM library. Error code = 0x"
			<< hex << hres << endl;
		return 1;                  // Program has failed.
	}

	// Step 2: --------------------------------------------------
	// Set general COM security levels --------------------------

	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 1;                    // Program has failed.
	}

	// Step 3: ---------------------------------------------------
	// Obtain the initial locator to WMI -------------------------

	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 1;                 // Program has failed.
	}

	// Step 4: -----------------------------------------------------
	// Connect to WMI through the IWbemLocator::ConnectServer method

	IWbemServices *pSvc = NULL;

	// Connect to the root\cimv2 namespace with
	// the current user and obtain pointer pSvc
	// to make IWbemServices calls.
	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 (for example, 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 1;                // Program has failed.
	}

	cout << "Connected to ROOT\\CIMV2 WMI namespace" << endl;


	// Step 5: --------------------------------------------------
	// Set security levels on the proxy -------------------------

	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 1;               // Program has failed.
	}

	// Step 6: --------------------------------------------------
	// Use the IWbemServices pointer to make requests of WMI ----

	// For example, get the name of the operating system
	IEnumWbemClassObject* pEnumerator = NULL;
	hres = pSvc->ExecQuery(
		bstr_t("WQL"),
		bstr_t("SELECT * FROM Win32_Processor"),
		WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
		NULL,
		&pEnumerator);

	if (FAILED(hres))
	{
		cout << "ExecQuery(...) failed."
			<< " Error code = 0x"
			<< hex << hres << endl;
		pSvc->Release();
		pLoc->Release();
		CoUninitialize();
		return 1;               // Program has failed.
	}

	// Step 7: -------------------------------------------------
	// Get the data from the query in step 6 -------------------

	IWbemClassObject *pclsObj = NULL;
	ULONG uReturn = 0;

	while (pEnumerator)
	{
		HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
			&pclsObj, &uReturn);

		if (0 == uReturn)
		{
			break;
		}

		VARIANT vtProp;

		// Get the value of the Name property
		hr = pclsObj->Get(L"Name", 0, &vtProp, 0, 0);
		wcout << " Name : " << vtProp.bstrVal << endl;
		VariantClear(&vtProp);

		pclsObj->Release();
	}

	// Cleanup
	// ========

	pSvc->Release();
	pLoc->Release();
	pEnumerator->Release();
	CoUninitialize();

	return 0; 
}

10、获取硬盘容量信息

https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getdiskfreespaceexa

BOOL GetDiskFreeSpaceExA(
  [in, optional]  LPCSTR          lpDirectoryName,
  [out, optional] PULARGE_INTEGER lpFreeBytesAvailableToCaller,
  [out, optional] PULARGE_INTEGER lpTotalNumberOfBytes,
  [out, optional] PULARGE_INTEGER lpTotalNumberOfFreeBytes
);

如下代码运行结果的容量单位为GB。

#include <windows.h>
#include <tchar.h>

long GetDiskSpaceInfo()
{
	long long all_Total = 0;
	DWORD dwSize = MAX_PATH;
	TCHAR szLogicalDrives[MAX_PATH] = { 0 };

	DWORD dwResult = GetLogicalDriveStrings(dwSize, szLogicalDrives);
	if (dwResult > 0 && dwResult <= MAX_PATH)
	{
		TCHAR* szSingleDrive = szLogicalDrives;
		while (*szSingleDrive)
		{
			uint64_t available, total, free;
			if (GetDiskFreeSpaceEx(szSingleDrive, (ULARGE_INTEGER*)&available, (ULARGE_INTEGER*)&total, (ULARGE_INTEGER*)&free))
			{
				double fTotal = total / 1024.0f / 1024.0f / 1024.0f;
				double fFree = free / 1024.0f / 1024.0f / 1024.0f;
				double fAvailable = available / 1024.0f / 1024.0f / 1024.0f;

				all_Total += total;
				std::cout << szSingleDrive << fTotal << "GB, " << fFree << "GB, " << fAvailable << "GB, " << std::endl;
			}

			// 获取下一个驱动器号起始地址
			szSingleDrive += _tcslen(szSingleDrive) + 1;
		}
	}

	return (long)(all_Total / 1024 / 1024 / 1024);
}