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

获取计算机硬件信息:

  • ​​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++获取计算机硬件信息(Windows)_win32_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;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

以上代码运行结果:
宽: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;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

以上代码运行结果:
宽: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;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

以上代码运行结果:
宽: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;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

以上代码运行结果:
宽: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;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

以上代码运行结果:
宽: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;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

以上代码运行结果:
宽: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;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.

 

auto dc = GetDC(nullptr);
auto x = GetDeviceCaps(dc, LOGPIXELSX);
auto y = GetDeviceCaps(dc, LOGPIXELSY);
ReleaseDC(nullptr, dc);
  • 1.
  • 2.
  • 3.
  • 4.

 

3、获取计算机名

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

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
);
  • 1.
  • 2.
  • 3.
  • 4.
BOOL GetComputerNameW(
[out] LPWSTR lpBuffer,
[in, out] LPDWORD nSize
);
  • 1.
  • 2.
  • 3.
  • 4.
#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 );
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

 

3.2 gethostname

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

 

int gethostname(
[out] char *name,
[in] int namelen
);
  • 1.
  • 2.
  • 3.
  • 4.

 

#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");
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.

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

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

 

BOOL GetUserNameA(
[out] LPSTR lpBuffer,
[in, out] LPDWORD pcbBuffer
);
  • 1.
  • 2.
  • 3.
  • 4.
BOOL GetUserNameW(
[out] LPWSTR lpBuffer,
[in, out] LPDWORD pcbBuffer
);
  • 1.
  • 2.
  • 3.
  • 4.
#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 );
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

 

5、获取计算机的IP地址

C++获取计算机硬件信息(Windows)_操作系统_05

5.1 gethostbyname

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

 

hostent *WSAAPI gethostbyname(
const char *name
);
  • 1.
  • 2.
  • 3.

 

#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");
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.

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++获取计算机硬件信息(Windows)_操作系统_06

 

 ​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;
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
void GetSystemInfo(
[out] LPSYSTEM_INFO lpSystemInfo
);
  • 1.
  • 2.
  • 3.

 

#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;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
  • 158.
  • 159.
  • 160.
  • 161.
  • 162.
  • 163.
  • 164.
  • 165.
  • 166.
  • 167.
  • 168.
  • 169.
  • 170.
  • 171.
  • 172.
  • 173.
  • 174.
  • 175.
  • 176.
  • 177.
  • 178.
  • 179.
  • 180.
  • 181.
  • 182.
  • 183.
  • 184.
  • 185.
  • 186.
  • 187.
  • 188.
  • 189.
  • 190.
  • 191.
  • 192.
  • 193.
  • 194.
  • 195.
  • 196.
  • 197.
  • 198.
  • 199.
  • 200.

7、获取内存信息

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

 

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

 

BOOL GlobalMemoryStatusEx(
[in, out] LPMEMORYSTATUSEX lpBuffer
);
  • 1.
  • 2.
  • 3.
typedef struct _MEMORYSTATUSEX {
DWORD dwLength;
DWORD dwMemoryLoad;
DWORDLONG ullTotalPhys;
DWORDLONG ullAvailPhys;
DWORDLONG ullTotalPageFile;
DWORDLONG ullAvailPageFile;
DWORDLONG ullTotalVirtual;
DWORDLONG ullAvailVirtual;
DWORDLONG ullAvailExtendedVirtual;
} MEMORYSTATUSEX, *LPMEMORYSTATUSEX;
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

 

#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");
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.

运行结果:

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

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();
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.

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;
}
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.

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
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.

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;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
  • 158.
  • 159.
  • 160.
  • 161.
  • 162.
  • 163.
  • 164.
  • 165.
  • 166.
  • 167.
  • 168.
  • 169.
  • 170.
  • 171.
  • 172.
  • 173.
  • 174.
  • 175.
  • 176.
  • 177.
  • 178.
  • 179.
  • 180.
  • 181.
  • 182.

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
);
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

 

如下代码运行结果的容量单位为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);
}