From b019c00825c4e9a17186bd37d0a9a451598d6d97 Mon Sep 17 00:00:00 2001 From: DevWiki Date: Tue, 12 Sep 2023 20:17:38 +0800 Subject: [PATCH] add --- WinDevice/Utils/CmdUtil.cpp | 15 ++ WinDevice/Utils/CmdUtil.h | 12 ++ WinDevice/Utils/SysInfoUtil.cpp | 218 +++++++++++++++++++++++----- WinDevice/Utils/SysInfoUtil.h | 7 +- WinDevice/Video/ScreenManager.cpp | 15 ++ WinDevice/Video/ScreenManager.h | 16 ++ WinDevice/WinDevice.cpp | 94 +++++++++++- WinDevice/WinDevice.vcxproj | 4 + WinDevice/WinDevice.vcxproj.filters | 12 ++ 9 files changed, 352 insertions(+), 41 deletions(-) create mode 100644 WinDevice/Utils/CmdUtil.cpp create mode 100644 WinDevice/Utils/CmdUtil.h create mode 100644 WinDevice/Video/ScreenManager.cpp create mode 100644 WinDevice/Video/ScreenManager.h diff --git a/WinDevice/Utils/CmdUtil.cpp b/WinDevice/Utils/CmdUtil.cpp new file mode 100644 index 0000000..e9c9a2d --- /dev/null +++ b/WinDevice/Utils/CmdUtil.cpp @@ -0,0 +1,15 @@ +#include "CmdUtil.h" + +#include +#include +#include +#include +#include + +using namespace std; + +std::string CmdUtil::ExecuteCommand(const std::string& command) +{ + + return ""; +} diff --git a/WinDevice/Utils/CmdUtil.h b/WinDevice/Utils/CmdUtil.h new file mode 100644 index 0000000..d195c68 --- /dev/null +++ b/WinDevice/Utils/CmdUtil.h @@ -0,0 +1,12 @@ + +#include +#include +#include +#include +#include + +class CmdUtil +{ +public: + static std::string ExecuteCommand(const std::string& command); +}; diff --git a/WinDevice/Utils/SysInfoUtil.cpp b/WinDevice/Utils/SysInfoUtil.cpp index caf006f..d514c88 100644 --- a/WinDevice/Utils/SysInfoUtil.cpp +++ b/WinDevice/Utils/SysInfoUtil.cpp @@ -4,6 +4,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -11,11 +14,114 @@ #include #include #include +#include #include "SysInfoUtil.h" using namespace std; +#define _CRT_NON_CONFORMING_SWPRINTFS +#define _CRT_SECURE_NO_WARNINGS + +#include +#include +#include +DEFINE_GUID(WmiMonitorID_GUID, 0x671a8285, 0x4edb, 0x4cae, 0x99, 0xfe, 0x69, 0xa1, 0x5c, 0x48, 0xc0, 0xbc); +typedef struct WmiMonitorID { + USHORT ProductCodeID[16]; + USHORT SerialNumberID[16]; + USHORT ManufacturerName[16]; + UCHAR WeekOfManufacture; + USHORT YearOfManufacture; + USHORT UserFriendlyNameLength; + USHORT UserFriendlyName[1]; +} WmiMonitorID, * PWmiMonitorID; +#define OFFSET_TO_PTR(Base, Offset) ((PBYTE)((PBYTE)Base + Offset)) + +typedef HRESULT(WINAPI* WOB) (IN LPGUID lpGUID, IN DWORD nAccess, OUT LONG*); +WOB WmiOpenBlock; +typedef HRESULT(WINAPI* WQAD) (IN LONG hWMIHandle, ULONG* nBufferSize, OUT UCHAR* pBuffer); +WQAD WmiQueryAllData; +typedef HRESULT(WINAPI* WCB) (IN LONG); +WCB WmiCloseBlock; + +void SysInfoUtil::GetInfoByEdid() +{ + HRESULT hr = E_FAIL; + LONG hWmiHandle; + PWmiMonitorID MonitorID; + HINSTANCE hDLL = LoadLibrary(L"Advapi32.dll"); + WmiOpenBlock = (WOB)GetProcAddress(hDLL, "WmiOpenBlock"); + WmiQueryAllData = (WQAD)GetProcAddress(hDLL, "WmiQueryAllDataW"); + WmiCloseBlock = (WCB)GetProcAddress(hDLL, "WmiCloseBlock"); + if (WmiOpenBlock != NULL && WmiQueryAllData && WmiCloseBlock) + { + WCHAR pszDeviceId[256] = L""; + hr = WmiOpenBlock((LPGUID)&WmiMonitorID_GUID, GENERIC_READ, &hWmiHandle); + if (hr == ERROR_SUCCESS) + { + ULONG nBufferSize = 0; + UCHAR* pAllDataBuffer = 0; + PWNODE_ALL_DATA pWmiAllData; + hr = WmiQueryAllData(hWmiHandle, &nBufferSize, 0); + if (hr == ERROR_INSUFFICIENT_BUFFER) + { + pAllDataBuffer = (UCHAR*)malloc(nBufferSize); + hr = WmiQueryAllData(hWmiHandle, &nBufferSize, pAllDataBuffer); + if (hr == ERROR_SUCCESS) + { + while (1) + { + pWmiAllData = (PWNODE_ALL_DATA)pAllDataBuffer; + if (pWmiAllData->WnodeHeader.Flags & WNODE_FLAG_FIXED_INSTANCE_SIZE) + MonitorID = (PWmiMonitorID)&pAllDataBuffer[pWmiAllData->DataBlockOffset]; + else + MonitorID = (PWmiMonitorID)&pAllDataBuffer[pWmiAllData->OffsetInstanceDataAndLength[0].OffsetInstanceData]; + + ULONG nOffset = 0; + WCHAR* pwsInstanceName = 0; + nOffset = (ULONG)pAllDataBuffer[pWmiAllData->OffsetInstanceNameOffsets]; + pwsInstanceName = (WCHAR*)OFFSET_TO_PTR(pWmiAllData, nOffset + sizeof(USHORT)); + WCHAR wsText[255] = L""; + wcout << L"Instance =" << pwsInstanceName << endl; + // swprintf(wsText, L"Instance Name = %s\r\n", pwsInstanceName); + OutputDebugString(wsText); + + WCHAR* pwsUserFriendlyName; + pwsUserFriendlyName = (WCHAR*)MonitorID->UserFriendlyName; + wcout << L"UserFriendlyName =" << pwsUserFriendlyName << endl; + // swprintf(wsText, L"User Friendly Name = %s\r\n", pwsUserFriendlyName); + OutputDebugString(wsText); + + WCHAR* pwsManufacturerName; + pwsManufacturerName = (WCHAR*)MonitorID->ManufacturerName; + wcout << L"ManufacturerName =" << pwsManufacturerName << endl; + // swprintf(wsText, L"Manufacturer Name = %s\r\n", pwsManufacturerName); + OutputDebugString(wsText); + + WCHAR* pwsProductCodeID; + pwsProductCodeID = (WCHAR*)MonitorID->ProductCodeID; + wcout << L"ProductCodeID =" << pwsProductCodeID << endl; + // swprintf(wsText, L"Product Code ID = %s\r\n", pwsProductCodeID); + OutputDebugString(wsText); + + WCHAR* pwsSerialNumberID; + pwsSerialNumberID = (WCHAR*)MonitorID->SerialNumberID; + wcout << L"SerialNumberID =" << pwsSerialNumberID << endl; + // swprintf(wsText, L"Serial Number ID = %s\r\n", pwsSerialNumberID); + OutputDebugString(wsText); + + if (!pWmiAllData->WnodeHeader.Linkage) + break; + pAllDataBuffer += pWmiAllData->WnodeHeader.Linkage; + } + free(pAllDataBuffer); + } + } + WmiCloseBlock(hWmiHandle); + } + } +} void SysInfoUtil::GetMacByGetAdaptersInfo(char* outMAC) const { @@ -185,28 +291,48 @@ 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)) { - std::wcout << L"name: " << monitorInfo.szDevice << std::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; + } + DISPLAYCONFIG_TARGET_DEVICE_NAME targetDeviceName = {}; + targetDeviceName.header.size = sizeof(targetDeviceName); - // 获取显示器的屏幕区域 - std::wcout << L"rect: left(" << lprcMonitor->left << ", " << lprcMonitor->top - << "), right(" << lprcMonitor->right << ", " << lprcMonitor->bottom << ")" << std::endl; + // 获取指定 HMONITOR 的目标设备名称信息 + if (DisplayConfigGetDeviceInfo(&targetDeviceName.header) == ERROR_SUCCESS) + { + wcout << L"Device Name: " << targetDeviceName.monitorFriendlyDeviceName << endl; + wcout << L"Source Name: " << targetDeviceName.monitorDevicePath << endl; - // 获取显示器的分辨率 - std::wcout << L"dpi: w=" << lprcMonitor->right - lprcMonitor->left - << ", h=" << lprcMonitor->bottom - lprcMonitor->top << std::endl; + // 获取指定 HMONITOR 的分辨率信息 + DEVMODE dm; + dm.dmSize = sizeof(DEVMODE); + dm.dmDriverExtra = 0; - std::wcout << L"===================" << std::endl; - } + if (EnumDisplaySettings(targetDeviceName.monitorDevicePath, ENUM_CURRENT_SETTINGS, &dm) != 0) + { + wcout << L"Resolution: " << dm.dmPelsWidth << L" x " << dm.dmPelsHeight << endl; + } + else + { + wcout << L"Failed to get display resolution." << endl; + } - - - return TRUE; - }, 0); + wcout << L"------------------------------------------" << endl; + } + else + { + wcout << L"Failed to get display device info." << endl; + } + return TRUE; + }, 0); wcout << "=====GetInfoByEnumDisplayMonitors end=====" << endl; } @@ -289,13 +415,21 @@ int SysInfoUtil::GetInfoByWMI() return 1; } - IEnumWbemClassObject* pEnum = nullptr; + IEnumWbemClassObject* pPnPEntity = nullptr; + hr = pServices->ExecQuery( + bstr_t("WQL"), + bstr_t("SELECT * FROM Win32_PnPEntity where service=\"monitor\""), + WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, + nullptr, + &pPnPEntity); + + IEnumWbemClassObject* pDesktopMonitor = nullptr; hr = pServices->ExecQuery( bstr_t("WQL"), bstr_t("SELECT * FROM Win32_DesktopMonitor"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, nullptr, - &pEnum); + &pDesktopMonitor); if (FAILED(hr)) { pServices->Release(); @@ -304,30 +438,46 @@ int SysInfoUtil::GetInfoByWMI() return 1; } - IWbemClassObject* pClassObject = nullptr; + IWbemClassObject* pPnPEntityClassObject = nullptr; ULONG uReturn = 0; - while (pEnum->Next(WBEM_INFINITE, 1, &pClassObject, &uReturn) == 0) { + while (pPnPEntity->Next(WBEM_INFINITE, 1, &pPnPEntityClassObject, &uReturn) == 0) { + VARIANT vtDeviceID; + VARIANT vtPNPDeviceID; + + hr = pPnPEntityClassObject->Get(L"DeviceID", 0, &vtDeviceID, 0, 0); + hr = pPnPEntityClassObject->Get(L"PNPDeviceID", 0, &vtPNPDeviceID, 0, 0); + + if (SUCCEEDED(hr) && vtDeviceID.vt == VT_BSTR && vtPNPDeviceID.vt == VT_BSTR) { + std::wcout << L"DeviceID: " << vtDeviceID.bstrVal << std::endl; + std::wcout << L"PNPDeviceID: " << vtPNPDeviceID.bstrVal << std::endl; + } + + pPnPEntityClassObject->Release(); + } + + IWbemClassObject* pDesktopMonitorClassObject = nullptr; + ULONG uDeskReturn = 0; + while (pDesktopMonitor->Next(WBEM_INFINITE, 1, &pDesktopMonitorClassObject, &uDeskReturn) == 0) { VARIANT vtDeviceID; VARIANT vtScreenWidth; VARIANT vtScreenHeight; - VARIANT vtModelName; + VARIANT vtPNPDeviceID; - 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); + hr = pDesktopMonitorClassObject->Get(L"DeviceID", 0, &vtDeviceID, 0, 0); + hr = pDesktopMonitorClassObject->Get(L"ScreenWidth", 0, &vtScreenWidth, 0, 0); + hr = pDesktopMonitorClassObject->Get(L"ScreenHeight", 0, &vtScreenHeight, 0, 0); + hr = pDesktopMonitorClassObject->Get(L"PNPDeviceID", 0, &vtPNPDeviceID, 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; + if (SUCCEEDED(hr) && vtDeviceID.vt == VT_BSTR && vtScreenWidth.vt == VT_I4 && vtScreenHeight.vt == VT_I4 ) { + std::wcout << L"DeviceID: " << vtDeviceID.bstrVal << std::endl; + std::wcout << L"size: " << vtScreenWidth.lVal << L"x" << vtScreenHeight.lVal << std::endl; } - pClassObject->Release(); + pDesktopMonitorClassObject->Release(); } - - pEnum->Release(); + pPnPEntity->Release(); + pDesktopMonitor->Release(); pServices->Release(); CoUninitialize(); wcout << L"=====GetInfoByWMI end=====" << endl; diff --git a/WinDevice/Utils/SysInfoUtil.h b/WinDevice/Utils/SysInfoUtil.h index e9cfb68..e218d78 100644 --- a/WinDevice/Utils/SysInfoUtil.h +++ b/WinDevice/Utils/SysInfoUtil.h @@ -16,9 +16,12 @@ public: static int GetInfoByQueryDisplayConfig(); - static void GetInfoByEnumDisplayDevicesA(); + static void GetInfoByEdid(); static int GetInfoByCfgmgr(); -private: + + + + }; diff --git a/WinDevice/Video/ScreenManager.cpp b/WinDevice/Video/ScreenManager.cpp new file mode 100644 index 0000000..fa0d943 --- /dev/null +++ b/WinDevice/Video/ScreenManager.cpp @@ -0,0 +1,15 @@ +#include "ScreenManager.h" + + +void SceenManager::UpdateDisplayInfo() +{ + +} + +void SceenManager::_UpdateDisplayDeviceList() +{ +} + +void SceenManager::_UpdateMonitorInfoMap() +{ +} diff --git a/WinDevice/Video/ScreenManager.h b/WinDevice/Video/ScreenManager.h new file mode 100644 index 0000000..5a003d8 --- /dev/null +++ b/WinDevice/Video/ScreenManager.h @@ -0,0 +1,16 @@ +#pragma once +#include +#include + +class SceenManager +{ +public: + void UpdateDisplayInfo(); + +private: + void _UpdateDisplayDeviceList(); + void _UpdateMonitorInfoMap(); + + std::vector _displayDeviceList; + std::map _hMonitorInfoMap; +}; diff --git a/WinDevice/WinDevice.cpp b/WinDevice/WinDevice.cpp index 01d9458..d9252a0 100644 --- a/WinDevice/WinDevice.cpp +++ b/WinDevice/WinDevice.cpp @@ -5,25 +5,109 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "Utils/SysInfoUtil.h" using namespace std; +std::string ExecuteCommandLine(std::string cmd); int main() { // 测量函数调用的耗时 auto start = chrono::high_resolution_clock::now(); - SysInfoUtil::GetInfoByEnumDisplayDevices(); - SysInfoUtil::GetInfoByEnumDisplayMonitors(); - SysInfoUtil::GetInfoByWMI(); - // SysInfoUtil::GetInfoByCfgmgr(); - SysInfoUtil::GetInfoByQueryDisplayConfig(); + // SysInfoUtil::GetInfoByEnumDisplayMonitors(); + // SysInfoUtil::GetInfoByQueryDisplayConfig(); + // SysInfoUtil::GetInfoByEnumDisplayDevices(); + // SysInfoUtil::GetInfoByWMI(); + // SysInfoUtil::GetInfoByEdid(); + // SysInfoUtil::GetInfoByQueryDisplayConfig(); + std::string command = "wmic desktopmonitor get PNPDeviceId,ScreenWidth,ScreenHeight"; + std::string commandOutput = ExecuteCommandLine(command); + // 使用 stringstream 分割命令输出 + stringstream ss(commandOutput); + string line; + + // 跳过第一行(属性名称) + getline(ss, line); + + while (getline(ss, line)) { + string pnpDeviceId, screenWidth, screenHeight; + + // 使用 stringstream 再次分割每行 + stringstream lineStream(line); + + // 读取属性值 + lineStream >> pnpDeviceId >> screenWidth >> screenHeight; + + // 输出解析的值 + cout << "PNPDeviceId: " << pnpDeviceId << ", ScreenWidth: " << screenWidth << ", ScreenHeight: " << screenHeight << endl; + } auto end = chrono::high_resolution_clock::now(); auto duration = chrono::duration_cast(end - start); wcout << "Function call duration: " << duration.count() << " ms" << endl; } + + +std::string ExecuteCommandLine(std::string cmd) +{ + + std::string cmd_result = std::string(); + + char psBuffer[0x2000] = { 0 }; + FILE* pPipe; + + /* Run DIR so that it writes its output to a pipe. Open this + * pipe with read text attribute so that we can read it + * like a text file. + */ + + if ((pPipe = _popen(cmd.c_str(), "rt")) == NULL) + { + exit(1); + } + + /* Read pipe until end of file, or an error occurs. */ + + while (fgets(psBuffer, 0x2000, pPipe)) + { + cmd_result += psBuffer; + memset(psBuffer, 0, 0x2000); + } + + int endOfFileVal = feof(pPipe); + int closeReturnVal = _pclose(pPipe); + + if (endOfFileVal) + { + printf("\nProcess returned %d\n", closeReturnVal); + } + else + { + printf("Error: Failed to read the pipe to the end.\n"); + } + + return cmd_result; +} + // 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单 // 调试程序: F5 或调试 >“开始调试”菜单 diff --git a/WinDevice/WinDevice.vcxproj b/WinDevice/WinDevice.vcxproj index 1f0661d..a06a9fd 100644 --- a/WinDevice/WinDevice.vcxproj +++ b/WinDevice/WinDevice.vcxproj @@ -146,14 +146,18 @@ + + + + diff --git a/WinDevice/WinDevice.vcxproj.filters b/WinDevice/WinDevice.vcxproj.filters index 27b1a08..d71cc9f 100644 --- a/WinDevice/WinDevice.vcxproj.filters +++ b/WinDevice/WinDevice.vcxproj.filters @@ -24,6 +24,12 @@ 源文件 + + 源文件 + + + 源文件 + @@ -38,5 +44,11 @@ 头文件 + + 头文件 + + + 头文件 + \ No newline at end of file