获取显示器信息

This commit is contained in:
DevWiki 2023-09-11 20:42:40 +08:00
parent 92bcf845bc
commit d9fb6fb6c8
6 changed files with 309 additions and 11 deletions

View File

@ -1,9 +1,22 @@
#include <stdafx.h>
#include <cstdio>
#include <iphlpapi.h>
#include <dxgi.h>
#include <vector>
#include <windows.h>
#include <cfgmgr32.h>
#include <comdef.h>
#include <Wbemidl.h>
#include <io.h>
#include <fcntl.h>
#include <chrono>
#include <iostream>
#include "SysInfoUtil.h"
using namespace std;
void SysInfoUtil::GetMacByGetAdaptersInfo(char* outMAC) const
{
ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
@ -39,3 +52,250 @@ void SysInfoUtil::GetMacByGetAdaptersInfo(char* outMAC) const
}
free(pAdapterInfo);
}
int SysInfoUtil::GetInfoByQueryDisplayConfig()
{
wcout << L"=====GetInfoByQueryDisplayConfig start=====" << endl;
std::vector<DISPLAYCONFIG_PATH_INFO> paths;
std::vector<DISPLAYCONFIG_MODE_INFO> modes;
UINT32 flags = QDC_ONLY_ACTIVE_PATHS;
LONG isError = ERROR_INSUFFICIENT_BUFFER;
UINT32 pathCount, modeCount;
isError = GetDisplayConfigBufferSizes(flags, &pathCount, &modeCount);
if (isError)
{
return 0;
}
// Allocate the path and mode arrays
paths.resize(pathCount);
modes.resize(modeCount);
// Get all active paths and their modes
isError = QueryDisplayConfig(flags, &pathCount, paths.data(), &modeCount, modes.data(), nullptr);
// The function may have returned fewer paths/modes than estimated
paths.resize(pathCount);
modes.resize(modeCount);
if (isError)
{
return 0;
}
// For each active path
int len = paths.size();
for (int i = 0; i < len; i++)
{
// Find the target (monitor) friendly name
DISPLAYCONFIG_TARGET_DEVICE_NAME targetName = {};
targetName.header.adapterId = paths[i].targetInfo.adapterId;
targetName.header.id = paths[i].targetInfo.id;
targetName.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME;
targetName.header.size = sizeof(targetName);
isError = DisplayConfigGetDeviceInfo(&targetName.header);
if (isError)
{
return 0;
}
wcout << "monitorFriendlyDeviceName:" << targetName.monitorFriendlyDeviceName << endl;
wcout << "monitorDevicePath:" << targetName.monitorDevicePath << endl;
}
wcout << "=====GetInfoByQueryDisplayConfig end=====" << endl;
}
int SysInfoUtil::GetInfoByCfgmgr()
{
wcout << "GetInfoByCfgmgr start" << endl;
DEVINST devInstRoot;
CONFIGRET cr = CM_Locate_DevNode(&devInstRoot, NULL, 0);
if (cr != CR_SUCCESS) {
// 处理错误
wcout << "GetInfoByCfgmgr error" << cr << endl;
return 0;
}
DEVINST devInstMonitor;
cr = CM_Get_Child(&devInstMonitor, devInstRoot, 0);
while (cr == CR_SUCCESS) {
// 在这里处理监视器设备
WCHAR displayName[1024];
ULONG displayNameSize = sizeof(displayName);
cr = CM_Get_DevNode_Registry_Property(devInstMonitor, CM_DRP_FRIENDLYNAME, NULL, displayName, &displayNameSize, 0);
if (cr == CR_SUCCESS) {
// displayName 包含显示名称
wcout << "displayName:" << displayName << endl;
}
WCHAR hardwareId[1024];
ULONG hardwareIdSize = sizeof(hardwareId);
cr = CM_Get_DevNode_Registry_Property(devInstMonitor, CM_DRP_HARDWAREID, NULL, hardwareId, &hardwareIdSize, 0);
if (cr == CR_SUCCESS) {
// hardwareId 包含硬件ID
wcout << "hardwareId:" << hardwareId << endl;
}
// 继续遍历下一个设备
cr = CM_Get_Sibling(&devInstMonitor, devInstMonitor, 0);
}
wcout << "GetInfoByCfgmgr end" << endl;
}
int SysInfoUtil::GetInfoByEnumDisplayDevices()
{
wcout << "=====GetInfoByEnumDisplayDevices start=====" << endl;
DISPLAY_DEVICE displayDevice;
displayDevice.cb = sizeof(DISPLAY_DEVICE);
DWORD deviceIndex = 0;
while (EnumDisplayDevices(NULL, deviceIndex, &displayDevice, 0))
{
std::wcout << "Display Device Name: " << displayDevice.DeviceName << std::endl;
std::wcout << "Display Device String: " << displayDevice.DeviceString << std::endl;
std::wcout << "Display Device ID: " << displayDevice.DeviceID << std::endl;
std::wcout << "Display Device Key: " << displayDevice.DeviceKey << std::endl;
deviceIndex++;
}
wcout << "=====GetInfoByEnumDisplayDevices end=====" << endl;
return 0;
}
void SysInfoUtil::GetInfoByEnumDisplayMonitors()
{
wcout << "=====GetInfoByEnumDisplayMonitors start=====" << endl;
// 枚举显示器
EnumDisplayMonitors(NULL, NULL, [](HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) -> BOOL {
MONITORINFOEX monitorInfo;
monitorInfo.cbSize = sizeof(MONITORINFOEX);
if (GetMonitorInfo(hMonitor, &monitorInfo)) {
// 输出友好名称
wcout << "szDevice:" << monitorInfo.szDevice << endl;
wcout << "right:" << monitorInfo.rcMonitor.right << endl;
wcout << "bottom:" << monitorInfo.rcMonitor.bottom << endl;
}
return TRUE;
}, 0);
wcout << "=====GetInfoByEnumDisplayMonitors end=====" << endl;
}
int SysInfoUtil::GetInfoByWMI()
{
wcout << "=====GetInfoByWMI start=====" << endl;
_setmode(_fileno(stdout), _O_U16TEXT);
HRESULT hr;
hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
if (FAILED(hr)) {
std::wcerr << L"COM 初始化失败!" << std::endl;
return 1;
}
hr = CoInitializeSecurity(
nullptr,
-1,
nullptr,
nullptr,
RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE,
nullptr,
EOAC_NONE,
nullptr);
if (FAILED(hr)) {
CoUninitialize();
std::wcerr << L"CoInitializeSecurity 失败!" << std::endl;
return 1;
}
IWbemLocator* pLocator = nullptr;
hr = CoCreateInstance(
CLSID_WbemLocator,
nullptr,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator,
reinterpret_cast<void**>(&pLocator));
if (FAILED(hr)) {
CoUninitialize();
std::wcerr << L"CoCreateInstance 失败!" << std::endl;
return 1;
}
IWbemServices* pServices = nullptr;
hr = pLocator->ConnectServer(
_bstr_t(L"ROOT\\CIMV2"),
nullptr,
nullptr,
0,
0,
0,
0,
&pServices);
pLocator->Release();
if (FAILED(hr)) {
CoUninitialize();
std::wcerr << L"ConnectServer 失败!" << std::endl;
return 1;
}
hr = CoSetProxyBlanket(
pServices,
RPC_C_AUTHN_WINNT,
RPC_C_AUTHZ_NONE,
nullptr,
RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE,
nullptr,
EOAC_NONE);
if (FAILED(hr)) {
pServices->Release();
CoUninitialize();
std::wcerr << L"CoSetProxyBlanket 失败!" << std::endl;
return 1;
}
IEnumWbemClassObject* pEnum = nullptr;
hr = pServices->ExecQuery(
bstr_t("WQL"),
bstr_t("SELECT * FROM Win32_DesktopMonitor"),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
nullptr,
&pEnum);
if (FAILED(hr)) {
pServices->Release();
CoUninitialize();
std::wcerr << L"ExecQuery 失败!" << std::endl;
return 1;
}
IWbemClassObject* pClassObject = nullptr;
ULONG uReturn = 0;
while (pEnum->Next(WBEM_INFINITE, 1, &pClassObject, &uReturn) == 0) {
VARIANT vtDeviceID;
VARIANT vtScreenWidth;
VARIANT vtScreenHeight;
VARIANT vtModelName;
hr = pClassObject->Get(L"DeviceID", 0, &vtDeviceID, 0, 0);
hr = pClassObject->Get(L"ScreenWidth", 0, &vtScreenWidth, 0, 0);
hr = pClassObject->Get(L"ScreenHeight", 0, &vtScreenHeight, 0, 0);
hr = pClassObject->Get(L"MonitorType", 0, &vtModelName, 0, 0);
if (SUCCEEDED(hr) && vtDeviceID.vt == VT_BSTR && vtScreenWidth.vt == VT_I4 && vtScreenHeight.vt == VT_I4 && vtModelName.vt == VT_BSTR) {
std::wcout << L"设备名称: " << vtDeviceID.bstrVal << std::endl;
std::wcout << L"分辨率: " << vtScreenWidth.lVal << L"x" << vtScreenHeight.lVal << std::endl;
std::wcout << L"型号: " << vtModelName.bstrVal << std::endl;
}
pClassObject->Release();
}
pEnum->Release();
pServices->Release();
CoUninitialize();
wcout << L"=====GetInfoByWMI end=====" << endl;
return 0;
}

View File

@ -1,9 +1,22 @@
#pragma once
#pragma comment(lib, "IPHLPAPI.lib")
#pragma comment(lib, "wbemuuid.lib")
class SysInfoUtil
{
public:
void GetMacByGetAdaptersInfo(char* outMAC) const;
static int GetInfoByWMI();
static void GetInfoByEnumDisplayMonitors();
static int GetInfoByEnumDisplayDevices();
static int GetInfoByQueryDisplayConfig();
static int GetInfoByCfgmgr();
private:
};

View File

@ -3,24 +3,25 @@
#include <chrono>
#include <iostream>
#include <windows.h>
#include <vector>
#include "Utils/SysInfoUtil.h"
using namespace std;
int main()
{
SysInfoUtil util;
char mac[18];
// 测量函数调用的耗时
auto start = chrono::high_resolution_clock::now();
util.GetMacByGetAdaptersInfo(mac);
auto start = chrono::high_resolution_clock::now();
SysInfoUtil::GetInfoByEnumDisplayDevices();
SysInfoUtil::GetInfoByEnumDisplayMonitors();
SysInfoUtil::GetInfoByWMI();
// SysInfoUtil::GetInfoByCfgmgr();
SysInfoUtil::GetInfoByQueryDisplayConfig();
auto end = chrono::high_resolution_clock::now();
auto duration = chrono::duration_cast<chrono::milliseconds>(end - start);
cout << "Function call duration: " << duration.count() << " ms" << endl;
// 输出日志信息
cout << "MAC address: " << mac << endl;
wcout << "Function call duration: " << duration.count() << " ms" << endl;
}
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单

View File

@ -23,7 +23,7 @@
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{fc07175f-ec7a-4ce5-9f7f-976dc6aed04d}</ProjectGuid>
<RootNamespace>WinDevice</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
@ -72,6 +72,7 @@
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
@ -93,6 +94,7 @@
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>dxgi.lib;cfgmgr32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

View File

@ -18,5 +18,25 @@
<ClCompile Include="WinDevice.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="Audio\AudioManager.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="Utils\SysInfoUtil.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Audio\AudioEnum.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="Audio\AudioManager.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="stdafx.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="Utils\SysInfoUtil.h">
<Filter>头文件</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -1,4 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
<PropertyGroup>
<ShowAllFiles>true</ShowAllFiles>
</PropertyGroup>
</Project>