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、获取屏幕分辨率
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]
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、获取计算机名
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地址
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 |
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、获取内存信息
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");
}
运行结果:
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);
}