添加设备检测

This commit is contained in:
DevWiki 2023-12-13 15:30:16 +08:00
parent ef9faa08c7
commit 91b7ea9e26
11 changed files with 382 additions and 13 deletions

3
.gitignore vendored
View File

@ -2,3 +2,6 @@
/.vs
/Debug
/*/Debug
/Release
/*/Release
x64/

View File

@ -0,0 +1,50 @@
#pragma once
#include "stdafx.h"
#include <iostream>
#include <vector>
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<HMONITOR> monitor;
std::string name;
long width;
long height;
};
struct UserDeviceInfo {
std::shared_ptr<CpuInfo> cpu;
std::shared_ptr<OsInfo> os;
std::shared_ptr<std::vector<GpuInfo>> gpu;
std::shared_ptr<std::vector<DisplayMonitorInfo>> monitor;
};
}

View File

@ -0,0 +1,245 @@
#include "WinDeviceManager.h"
#include "stdafx.h"
#include <ddraw.h>
#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<CpuInfo>(*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>(*osInfo);
userInfo.cpu = std::make_shared<CpuInfo>(*cpuInfo);
userInfo.gpu = std::make_shared<std::vector<GpuInfo>>(*gpuInfos);
userInfo.monitor = std::make_shared<std::vector<DisplayMonitorInfo>>(*monitorInfos);
return userInfo;
}
#pragma warning(disable : 4996)
void WinDeviceManager::_UpdateOperatingSystemInfo()
{
if (!osInfo)
{
osInfo = std::make_shared<OsInfo>(*osInfo);
}
// 获取操作系统版本信息
OSVERSIONINFO osvi;
ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osvi);
osInfo->name = Wstring2String(osvi.szCSDVersion);
osInfo->majorVersion = static_cast<unsigned long>(osvi.dwMajorVersion);
osInfo->minorVersion = static_cast<unsigned long>(osvi.dwMinorVersion);
osInfo->buildNumber = static_cast<unsigned long>(osvi.dwBuildNumber);
// 获取系统内存信息
MEMORYSTATUSEX memStatus;
ZeroMemory(&memStatus, sizeof(MEMORYSTATUSEX));
memStatus.dwLength = sizeof(MEMORYSTATUSEX);
GlobalMemoryStatusEx(&memStatus);
osInfo->totalMemory = static_cast<int64_t>(memStatus.ullTotalPhys / (1024 * 1024));
}
void WinDeviceManager::_UpdateGpuInfo()
{
if (!gpuInfos)
{
gpuInfos = std::make_shared<std::vector<GpuInfo>>(*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<uint32_t>(adapter_desc.DeviceId);
gpuInfo.vendorId = static_cast<uint32_t>(adapter_desc.VendorId);
gpuInfo.vram = static_cast<size_t>(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>(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<std::vector<DisplayMonitorInfo>>(*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<void**>(&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;
}
}

View File

@ -0,0 +1,32 @@
#pragma once
#include <memory>
#include "UserDeviceInfo.h"
#include <Mmdeviceapi.h>
namespace WinDevice
{
class WinDeviceManager {
public:
WinDeviceManager();
~WinDeviceManager();
UserDeviceInfo GetUserDeviceInfo();
static bool IsDirectDrawAccelerationAvailable();
static bool IsDirect3DAccelerationAvailable();
static bool IsDirectX12Available();
private:
std::shared_ptr<OsInfo> osInfo;
std::shared_ptr<CpuInfo> cpuInfo;
std::shared_ptr<std::vector<GpuInfo>> gpuInfos;
std::shared_ptr<std::vector<DisplayMonitorInfo>> 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();
};
}

View File

@ -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...)

View File

@ -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<std::string>(input);
}
std::string Wchar2String(const WCHAR* input) {
inline std::string Wchar2String(const WCHAR* input) {
std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
return converter.to_bytes(input);
}

View File

@ -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 或调试 >“开始执行(不调试)”菜单

View File

@ -87,14 +87,14 @@
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);SPDLOG_WCHAR_FILENAMES</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(ProjectDir)include\third_lib\;.</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>dxgi.lib;cfgmgr32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>dxgi.lib;cfgmgr32.lib;d3d9.lib;d3d12.lib;ddraw.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@ -105,13 +105,14 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>.;</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)include\third_lib\;.</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>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)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@ -120,11 +121,12 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>.;</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)include\third_lib\;.</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>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)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@ -135,17 +137,19 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>.;</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)include\third_lib\;.</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>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)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="Audio\AudioManager.cpp" />
<ClCompile Include="Device\WinDeviceManager.cpp" />
<ClCompile Include="Utils\CmdUtil.cpp" />
<ClCompile Include="Utils\Log.cpp" />
<ClCompile Include="Utils\SysInfoUtil.cpp" />
@ -156,6 +160,8 @@
<ItemGroup>
<ClInclude Include="Audio\AudioEnum.h" />
<ClInclude Include="Audio\AudioManager.h" />
<ClInclude Include="Device\UserDeviceInfo.h" />
<ClInclude Include="Device\WinDeviceManager.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="Utils\CmdUtil.h" />
<ClInclude Include="Utils\Log.h" />

View File

@ -36,6 +36,9 @@
<ClCompile Include="Utils\Log.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="Device\WinDeviceManager.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Audio\AudioEnum.h">
@ -65,5 +68,11 @@
<ClInclude Include="Utils\StringUtil.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="Device\UserDeviceInfo.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="Device\WinDeviceManager.h">
<Filter>头文件</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -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
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

View File

@ -7,3 +7,19 @@
#include <Psapi.h>
#include <Shellapi.h>
#include "dxgi.h"
#include "WinUser.h"
#include <dxgi1_4.h>
#include <d3d9.h>
#include <d3d9caps.h>
#include <d3d12.h>
#include <DirectXMath.h>
#include <Dwrite.h>
#include <intrin.h>
#include "sysinfoapi.h"