From 91b7ea9e260b3d76cdd5924aaafed7c79432d2d6 Mon Sep 17 00:00:00 2001 From: DevWiki Date: Wed, 13 Dec 2023 15:30:16 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=AE=BE=E5=A4=87=E6=A3=80?= =?UTF-8?q?=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 + WinDevice/Device/UserDeviceInfo.h | 50 ++++ WinDevice/Device/WinDeviceManager.cpp | 245 +++++++++++++++++++ WinDevice/Device/WinDeviceManager.h | 32 +++ WinDevice/Utils/Log.cpp | 2 +- WinDevice/Utils/StringUtil.h | 4 +- WinDevice/WinDevice.cpp | 16 +- WinDevice/WinDevice.vcxproj | 16 +- WinDevice/WinDevice.vcxproj.filters | 9 + WinDevice/include/third_lib/spdlog/tweakme.h | 2 +- WinDevice/stdafx.h | 16 ++ 11 files changed, 382 insertions(+), 13 deletions(-) create mode 100644 WinDevice/Device/UserDeviceInfo.h create mode 100644 WinDevice/Device/WinDeviceManager.cpp create mode 100644 WinDevice/Device/WinDeviceManager.h diff --git a/.gitignore b/.gitignore index 748d660..ab93116 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,6 @@ /.vs /Debug /*/Debug +/Release +/*/Release +x64/ diff --git a/WinDevice/Device/UserDeviceInfo.h b/WinDevice/Device/UserDeviceInfo.h new file mode 100644 index 0000000..fb6bbfd --- /dev/null +++ b/WinDevice/Device/UserDeviceInfo.h @@ -0,0 +1,50 @@ +#pragma once +#include "stdafx.h" +#include +#include + +namespace WinDevice { + struct OsInfo { + // 操作系统名称 + std::string name; + unsigned long majorVersion; + unsigned long minorVersion; + unsigned long buildNumber; + // 总内存大小(以字节为单位) + int64_t totalMemory; + }; + + struct CpuInfo { + std::string name; + int coreCout; + }; + + struct GpuInfo { + std::string name; + /** + * \brief 厂商Id + * + * 可能的值: + * - NVIDIA:0x10DE + * - Intel :0x8086 + * - AMD :0x1002 + */ + uint32_t vendorId; + uint32_t deviceId; + size_t vram; + }; + + struct DisplayMonitorInfo { + std::shared_ptr monitor; + std::string name; + long width; + long height; + }; + + struct UserDeviceInfo { + std::shared_ptr cpu; + std::shared_ptr os; + std::shared_ptr> gpu; + std::shared_ptr> monitor; + }; +} diff --git a/WinDevice/Device/WinDeviceManager.cpp b/WinDevice/Device/WinDeviceManager.cpp new file mode 100644 index 0000000..2dee472 --- /dev/null +++ b/WinDevice/Device/WinDeviceManager.cpp @@ -0,0 +1,245 @@ +#include "WinDeviceManager.h" +#include "stdafx.h" +#include +#include "../Utils/StringUtil.h" + +namespace WinDevice +{ + WinDeviceManager::WinDeviceManager() + { + } + + WinDeviceManager::~WinDeviceManager() + { + } + + void WinDeviceManager::_UpdateCpuInfo() + { + SYSTEM_INFO sysInfo; + GetSystemInfo(&sysInfo); + + // 获取CPU信息 + int cpuInfo[4] = {-1}; + __cpuid(cpuInfo, 0); + unsigned int maxCpuId = cpuInfo[0]; + + char cpuBrandString[0x40]; + memset(cpuBrandString, 0, sizeof(cpuBrandString)); + + for (unsigned int i = 0x80000002; i <= 0x80000004; ++i) + { + __cpuid(cpuInfo, i); + memcpy(cpuBrandString + (i - 0x80000002) * 16, cpuInfo, sizeof(cpuInfo)); + } + if (!this->cpuInfo) + { + this->cpuInfo = std::make_shared(*this->cpuInfo); + } + this->cpuInfo->name = std::string(cpuBrandString); + this->cpuInfo->coreCout = sysInfo.dwNumberOfProcessors; + } + + UserDeviceInfo WinDeviceManager::GetUserDeviceInfo() + { + UserDeviceInfo userInfo; + + _UpdateOperatingSystemInfo(); + _UpdateCpuInfo(); + _UpdateGpuInfo(); + // 每次获取主要是因为显示器可能发生变化 + _UpdateMonitorInfo(); + + userInfo.os = std::make_shared(*osInfo); + userInfo.cpu = std::make_shared(*cpuInfo); + userInfo.gpu = std::make_shared>(*gpuInfos); + userInfo.monitor = std::make_shared>(*monitorInfos); + + return userInfo; + } + #pragma warning(disable : 4996) + void WinDeviceManager::_UpdateOperatingSystemInfo() + { + if (!osInfo) + { + osInfo = std::make_shared(*osInfo); + } + // 获取操作系统版本信息 + OSVERSIONINFO osvi; + ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&osvi); + osInfo->name = Wstring2String(osvi.szCSDVersion); + osInfo->majorVersion = static_cast(osvi.dwMajorVersion); + osInfo->minorVersion = static_cast(osvi.dwMinorVersion); + osInfo->buildNumber = static_cast(osvi.dwBuildNumber); + + // 获取系统内存信息 + MEMORYSTATUSEX memStatus; + ZeroMemory(&memStatus, sizeof(MEMORYSTATUSEX)); + memStatus.dwLength = sizeof(MEMORYSTATUSEX); + GlobalMemoryStatusEx(&memStatus); + osInfo->totalMemory = static_cast(memStatus.ullTotalPhys / (1024 * 1024)); + } + + void WinDeviceManager::_UpdateGpuInfo() + { + if (!gpuInfos) + { + gpuInfos = std::make_shared>(*gpuInfos); + } + gpuInfos->clear(); + IDXGIFactory* pFactory = nullptr; + CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)(&pFactory)); + IDXGIAdapter* pAdapter = nullptr; + bool isFind = false; + for (UINT adapterIndex = 0; pFactory->EnumAdapters(adapterIndex, &pAdapter) != DXGI_ERROR_NOT_FOUND; ++ + adapterIndex) + { + DXGI_ADAPTER_DESC adapter_desc; + pAdapter->GetDesc(&adapter_desc); + GpuInfo gpuInfo; + gpuInfo.name = Wstring2String(adapter_desc.Description); + gpuInfo.deviceId = static_cast(adapter_desc.DeviceId); + gpuInfo.vendorId = static_cast(adapter_desc.VendorId); + gpuInfo.vram = static_cast(adapter_desc.DedicatedVideoMemory); + gpuInfos->push_back(gpuInfo); + } + pFactory->Release(); + } + + BOOL WinDeviceManager::_EnumMonitorProc(HMONITOR hMonitor) + { + MONITORINFOEXA miex; + miex.cbSize = sizeof(miex); + + if (GetMonitorInfoA(hMonitor, (LPMONITORINFO)&miex)) + { + DisplayMonitorInfo info; + info.monitor = std::make_shared(hMonitor); + info.name = miex.szDevice; + info.width = miex.rcMonitor.right - miex.rcMonitor.left; + info.height = miex.rcMonitor.bottom - miex.rcMonitor.top; + monitorInfos->push_back(info); + } + return TRUE; + } + + BOOL CALLBACK WinDeviceManager::Monitor_enum_proc_(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) + { + return ((WinDeviceManager*)dwData)->_EnumMonitorProc(hMonitor); + } + + void WinDeviceManager::_UpdateMonitorInfo() + { + if (!monitorInfos) + { + monitorInfos = std::make_shared>(*monitorInfos); + } + monitorInfos->clear(); + ::EnumDisplayMonitors(NULL, NULL, Monitor_enum_proc_, (LPARAM)this); + } + + bool WinDeviceManager::IsDirectDrawAccelerationAvailable() + { + IDirectDraw* pDirectDraw = nullptr; + + HRESULT hr = DirectDrawCreate(nullptr, &pDirectDraw, nullptr); + if (FAILED(hr)) + { + // DirectDraw 创建失败,可能是不支持或没有安装 DirectX + return false; + } + + // 获取 DirectDraw 加速信息 + DDCAPS ddcaps; + ZeroMemory(&ddcaps, sizeof(ddcaps)); + ddcaps.dwSize = sizeof(ddcaps); + + hr = pDirectDraw->GetCaps(&ddcaps, nullptr); + pDirectDraw->Release(); + + if (FAILED(hr)) + { + // 获取 DirectDraw 加速信息失败 + return false; + } + + // 检查是否支持硬件加速 + return (ddcaps.dwCaps & DDCAPS_NOHARDWARE) == 0; + } + + bool WinDeviceManager::IsDirect3DAccelerationAvailable() + { + IDirect3D9* pD3D = Direct3DCreate9(D3D_SDK_VERSION); + + if (pD3D == nullptr) + { + // DirectX is not installed or not available + return false; + } + + D3DCAPS9 caps; + if (FAILED(pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps))) + { + // Failed to get device capabilities + pD3D->Release(); + return false; + } + + // Check if Direct3D acceleration is supported + const bool accelerationAvailable = (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0; + + pD3D->Release(); + + return accelerationAvailable; + } + + bool WinDeviceManager::IsDirectX12Available() + { + HRESULT hr = S_OK; + + // 初始化 COM 环境 + hr = CoInitialize(nullptr); + if (FAILED(hr)) + { + // 处理初始化失败的情况 + return false; + } + + // 创建 DXGI 工厂 + IDXGIFactory4* pFactory = nullptr; + hr = CreateDXGIFactory1(__uuidof(IDXGIFactory4), reinterpret_cast(&pFactory)); + if (FAILED(hr)) + { + // 处理工厂创建失败的情况 + CoUninitialize(); + return false; + } + + // 枚举适配器 + IDXGIAdapter1* pAdapter = nullptr; + for (UINT adapterIndex = 0; pFactory->EnumAdapters1(adapterIndex, &pAdapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex) + { + // 检查适配器是否支持 DirectX 12 + D3D_FEATURE_LEVEL featureLevels[] = {D3D_FEATURE_LEVEL_12_0, D3D_FEATURE_LEVEL_12_1}; + for (const D3D_FEATURE_LEVEL featureLevel : featureLevels) + { + hr = D3D12CreateDevice(pAdapter, featureLevel, __uuidof(ID3D12Device), nullptr); + if (SUCCEEDED(hr)) + { + // 找到支持 DirectX 12 的适配器 + pAdapter->Release(); + pFactory->Release(); + CoUninitialize(); + return true; + } + } + pAdapter->Release(); + } + + // 未找到支持 DirectX 12 的适配器 + pFactory->Release(); + CoUninitialize(); + return false; + } +} diff --git a/WinDevice/Device/WinDeviceManager.h b/WinDevice/Device/WinDeviceManager.h new file mode 100644 index 0000000..24a0951 --- /dev/null +++ b/WinDevice/Device/WinDeviceManager.h @@ -0,0 +1,32 @@ +#pragma once +#include + +#include "UserDeviceInfo.h" +#include + +namespace WinDevice +{ + class WinDeviceManager { + public: + WinDeviceManager(); + ~WinDeviceManager(); + + UserDeviceInfo GetUserDeviceInfo(); + static bool IsDirectDrawAccelerationAvailable(); + static bool IsDirect3DAccelerationAvailable(); + static bool IsDirectX12Available(); + + private: + std::shared_ptr osInfo; + std::shared_ptr cpuInfo; + std::shared_ptr> gpuInfos; + std::shared_ptr> monitorInfos; + + void _UpdateOperatingSystemInfo(); + void _UpdateCpuInfo(); + void _UpdateGpuInfo(); + BOOL _EnumMonitorProc(HMONITOR hMonitor); + static BOOL CALLBACK Monitor_enum_proc_(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData); + void _UpdateMonitorInfo(); + }; +} diff --git a/WinDevice/Utils/Log.cpp b/WinDevice/Utils/Log.cpp index d67894f..ae08b88 100644 --- a/WinDevice/Utils/Log.cpp +++ b/WinDevice/Utils/Log.cpp @@ -4,7 +4,7 @@ void Log::Init(LogLevel level, std::string fileName) { - + spdlog::set_pattern("[%H:%M:%S %z] [%n] [%^---%L---%$] [thread %t] %v"); } void Log::Info(std::string format, std::string args...) diff --git a/WinDevice/Utils/StringUtil.h b/WinDevice/Utils/StringUtil.h index 1236658..cb5c9af 100644 --- a/WinDevice/Utils/StringUtil.h +++ b/WinDevice/Utils/StringUtil.h @@ -11,11 +11,11 @@ To Convert(const From& input) { return converter.to_bytes(input); } -std::string Wstring2String(const std::wstring& input) { +inline std::string Wstring2String(const std::wstring& input) { return Convert(input); } -std::string Wchar2String(const WCHAR* input) { +inline std::string Wchar2String(const WCHAR* input) { std::wstring_convert> converter; return converter.to_bytes(input); } diff --git a/WinDevice/WinDevice.cpp b/WinDevice/WinDevice.cpp index d8c7a86..8fc312a 100644 --- a/WinDevice/WinDevice.cpp +++ b/WinDevice/WinDevice.cpp @@ -11,15 +11,23 @@ #include "Utils/CmdUtil.h" #include "Video/ScreenManager.h" +#include "Device/WinDeviceManager.h" using namespace std; int main() { - const std::string command = "wmic desktopmonitor get PNPDeviceId,ScreenWidth,ScreenHeight"; - const std::string command_output = CmdUtil::ExecuteCommand(command); - ScreenManager sceen_manager; - sceen_manager.UpdateDisplayInfo(); + // const std::string command = "wmic desktopmonitor get PNPDeviceId,ScreenWidth,ScreenHeight"; + // const std::string command_output = CmdUtil::ExecuteCommand(command); + // spdlog::info(L"xxxx"); + // ScreenManager sceen_manager; + // sceen_manager.UpdateDisplayInfo(); + + spdlog::info("IsDirectX12Available: {0}", WinDevice::WinDeviceManager::IsDirectX12Available()); + spdlog::info("IsDirect3DAccelerationAvailable: {0}", WinDevice::WinDeviceManager::IsDirect3DAccelerationAvailable()); + spdlog::info("IsDirectDrawAccelerationAvailable: {0}", WinDevice::WinDeviceManager::IsDirectDrawAccelerationAvailable()); + getchar(); + return 0; } // 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单 diff --git a/WinDevice/WinDevice.vcxproj b/WinDevice/WinDevice.vcxproj index 9c36d83..dd58105 100644 --- a/WinDevice/WinDevice.vcxproj +++ b/WinDevice/WinDevice.vcxproj @@ -87,14 +87,14 @@ Level3 true - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);SPDLOG_WCHAR_FILENAMES true $(ProjectDir)include\third_lib\;. Console true - dxgi.lib;cfgmgr32.lib;%(AdditionalDependencies) + dxgi.lib;cfgmgr32.lib;d3d9.lib;d3d12.lib;ddraw.lib;%(AdditionalDependencies) @@ -105,13 +105,14 @@ true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true - .; + $(ProjectDir)include\third_lib\;. Console true true true + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dxgi.lib;cfgmgr32.lib;d3d9.lib;d3d12.lib;ddraw.lib;%(AdditionalDependencies) @@ -120,11 +121,12 @@ true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true - .; + $(ProjectDir)include\third_lib\;. Console true + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dxgi.lib;cfgmgr32.lib;d3d9.lib;d3d12.lib;ddraw.lib;%(AdditionalDependencies) @@ -135,17 +137,19 @@ true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true - .; + $(ProjectDir)include\third_lib\;. Console true true true + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dxgi.lib;cfgmgr32.lib;d3d9.lib;d3d12.lib;ddraw.lib;%(AdditionalDependencies) + @@ -156,6 +160,8 @@ + + diff --git a/WinDevice/WinDevice.vcxproj.filters b/WinDevice/WinDevice.vcxproj.filters index dacede8..3f69a31 100644 --- a/WinDevice/WinDevice.vcxproj.filters +++ b/WinDevice/WinDevice.vcxproj.filters @@ -36,6 +36,9 @@ 源文件 + + 源文件 + @@ -65,5 +68,11 @@ 头文件 + + 头文件 + + + 头文件 + \ No newline at end of file diff --git a/WinDevice/include/third_lib/spdlog/tweakme.h b/WinDevice/include/third_lib/spdlog/tweakme.h index 5bcb5ff..e734a75 100644 --- a/WinDevice/include/third_lib/spdlog/tweakme.h +++ b/WinDevice/include/third_lib/spdlog/tweakme.h @@ -90,7 +90,7 @@ /////////////////////////////////////////////////////////////////////////////// // Uncomment to enable wchar_t support (convert to utf8) // -// #define SPDLOG_WCHAR_TO_UTF8_SUPPORT +#define SPDLOG_WCHAR_TO_UTF8_SUPPORT /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// diff --git a/WinDevice/stdafx.h b/WinDevice/stdafx.h index f1e0469..0805be4 100644 --- a/WinDevice/stdafx.h +++ b/WinDevice/stdafx.h @@ -7,3 +7,19 @@ #include #include + +#include "dxgi.h" +#include "WinUser.h" +#include +#include +#include +#include + +#include +#include + +#include + +#include "sysinfoapi.h" + +