当前位置 : 主页 > 操作系统 > centos >

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

来源:互联网 收集:自由互联 发布时间:2023-09-07
“流水下山非有意, 片云归洞本无心;人生若得如云水, 铁树开花遍界春。” 获取计算机硬件信息: ​​1、获取屏幕分辨率​​ ​​1.1 GetSystemMetrics​​ ​​1.2 GetDeviceCaps​​ ​​


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


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

获取计算机硬件信息:

  • ​​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;
}

以上代码运行结果:
宽: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、获取屏幕显示比例

  • ​​GetDpiForWindow function (winuser.h)​​
  • ​​与 c + + Windows,为 Windows 8.1 编写高 DPI 应用​​

  • Minimum supported client Windows 10, version 1607 [desktop apps only]
  • C++获取计算机硬件信息(Windows)_c++_03

  • DPI 的基值定义为 USER _ DEFAULT SCREEN _ _ DPI, 设置为 96。 若要确定监视器的缩放因子,请取 DPI 值并除以 USER _ DEFAULT SCREEN _ _ DPI。 下表提供了一些示例 DPI 值和相关缩放因子。

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++获取计算机硬件信息(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
);
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++获取计算机硬件信息(Windows)_win32_05

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++获取计算机硬件信息(Windows)_win32_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;
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++获取计算机硬件信息(Windows)_win32_07


​​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++获取计算机硬件信息(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();
}

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 数据​​
  • ​​计算机系统硬件类​​

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);
}

结语

​如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;​​​╮( ̄▽ ̄)╭
​​​如果您感觉方法或代码不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进;​​​o_O???
​​​如果您需要相关功能的代码定制化开发,可以留言私信作者;​​​(✿◡‿◡)
​​​感谢各位大佬童鞋们的支持!​​( ´ ▽´ )ノ ( ´ ▽´)っ!!!



【文章转自高防服务器 http://www.558idc.com 复制请保留原URL】
网友评论