デバイス情報要素の文字列プロパティ(概要、クラス、クラスGUID、フレンドリーネーム、ハードウェアID)を列挙するコードです。再利用可能なコードをUtility.hpp
へ移動しています。
文字列プロパティ(概要、クラス、クラスGUID、フレンドリーネーム、ハードウェアID)を列挙する
Main.cpp
#pragma comment(lib, "SetupAPI.lib") #define STRICT #define NOMINMAX #include <Windows.h> #include <SetupAPI.h> #include "Utility.hpp" #include <iostream> #include <format> int main() { std::wcout.imbue(std::locale("", std::locale::ctype)); auto DevInfoHandle{ unique_SetupDiGetClassDevsW( nullptr, nullptr, nullptr, DIGCF_ALLCLASSES) }; // ループ中で繰り返し使用するバッファーの用意 std::wstring DevDesc; std::wstring DevClass; std::wstring DevClassGuid; std::wstring DevFriendlyName; std::wstring DevHardwareId; std::wcout << L"ClassGuid, DevInst, SPDRP_DEVICEDESC, SPDRP_CLASS, SPDRP_CLASSGUID, SPDRP_FRIENDLYNAME, SPDRP_HARDWAREID" << std::endl; for (auto& DevInfoData : SetupDiCreateDeviceInfoDataList(DevInfoHandle.get())) { SetupDiGetDeviceRegistryPropertyAsStringW(DevDesc, DevInfoHandle.get(), &DevInfoData, SPDRP_DEVICEDESC); SetupDiGetDeviceRegistryPropertyAsStringW(DevClass, DevInfoHandle.get(), &DevInfoData, SPDRP_CLASS); SetupDiGetDeviceRegistryPropertyAsStringW(DevClassGuid, DevInfoHandle.get(), &DevInfoData, SPDRP_CLASSGUID); SetupDiGetDeviceRegistryPropertyAsStringW(DevFriendlyName, DevInfoHandle.get(), &DevInfoData, SPDRP_FRIENDLYNAME); SetupDiGetDeviceRegistryPropertyAsStringW(DevHardwareId, DevInfoHandle.get(), &DevInfoData, SPDRP_HARDWAREID); std::wcout << std::format(L"{}, {}, {}, {}, {}, {}, {}", GUIDToWString(DevInfoData.ClassGuid), DevInfoData.DevInst, DevDesc.c_str(), DevClass.c_str(), DevClassGuid.c_str(), DevFriendlyName.c_str(), DevHardwareId.c_str()) << std::endl; } }
Utility.hpp
//----------------------------------------------------------------------------- // Utility.hpp // 再利用可能なコードを定義します。 //----------------------------------------------------------------------------- #pragma once #include <bit> #include <memory> #include <string> #include <numeric> #include <list> //----------------------------------------------------------------------------- // GUID -> wstring //----------------------------------------------------------------------------- std::wstring GUIDToWString(const GUID& guid) { std::wstring s(38, L'\0'); if (FAILED(::StringFromGUID2(guid, s.data(), 38))) return {}; return std::move(s); } //----------------------------------------------------------------------------- // Setup API wrappers //----------------------------------------------------------------------------- struct HDEVINFO_deleter { void operator() (HDEVINFO handle) const noexcept { ::SetupDiDestroyDeviceInfoList(handle); } }; using unique_HDEVINFO = std::unique_ptr<std::remove_pointer_t<HDEVINFO>, HDEVINFO_deleter>; unique_HDEVINFO unique_SetupDiGetClassDevsW( const GUID* ClassGuid, LPCWSTR Enumerator, HWND hWndParent, DWORD Flags) noexcept { return unique_HDEVINFO(::SetupDiGetClassDevsW(ClassGuid, Enumerator, hWndParent, Flags)); } std::list<SP_DEVINFO_DATA> SetupDiCreateDeviceInfoDataList(HDEVINFO DeviceInfoSet) { std::list<SP_DEVINFO_DATA> DevInfoDatas; for (DWORD i = 0; i < std::numeric_limits<DWORD>::max(); i++) { SP_DEVINFO_DATA DevInfoData{ sizeof(SP_DEVINFO_DATA) }; if (!SetupDiEnumDeviceInfo(DeviceInfoSet, i, &DevInfoData)) break; DevInfoDatas.emplace_back(DevInfoData); } return std::move(DevInfoDatas); } BOOL SetupDiGetDeviceRegistryPropertyAsStringW( std::wstring& result, HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Property) { DWORD RequiredSize; DWORD PropertyRegDataType; if (!::SetupDiGetDeviceRegistryPropertyW(DeviceInfoSet, DeviceInfoData, Property, &PropertyRegDataType, nullptr, 0, &RequiredSize) && ::GetLastError() != ERROR_INSUFFICIENT_BUFFER) { return FALSE; } if (PropertyRegDataType != REG_SZ) { ::SetLastError(ERROR_INVALID_DATATYPE); return FALSE; } result.resize(RequiredSize); return ::SetupDiGetDeviceRegistryPropertyW(DeviceInfoSet, DeviceInfoData, Property, nullptr, std::bit_cast<PBYTE>(result.data()), result.size(), nullptr); }
クラスを列挙する
//----------------------------------------------------------------------------- // Utility.hpp // 再利用可能なコードを定義します。 //----------------------------------------------------------------------------- #pragma once #include <bit> #include <memory> #include <string> #include <numeric> #include <list> //----------------------------------------------------------------------------- // GUID -> wstring //----------------------------------------------------------------------------- std::wstring GUIDToWString(const GUID& guid) { std::wstring s(38, L'\0'); if (FAILED(::StringFromGUID2(guid, s.data(), 38))) return {}; return std::move(s); } //----------------------------------------------------------------------------- // Setup API wrappers //----------------------------------------------------------------------------- struct HDEVINFO_deleter { void operator() (HDEVINFO handle) const noexcept { ::SetupDiDestroyDeviceInfoList(handle); } }; using unique_HDEVINFO = std::unique_ptr<std::remove_pointer_t<HDEVINFO>, HDEVINFO_deleter>; unique_HDEVINFO unique_SetupDiGetClassDevsW( const GUID* ClassGuid, LPCWSTR Enumerator, HWND hWndParent, DWORD Flags) noexcept { return unique_HDEVINFO(::SetupDiGetClassDevsW(ClassGuid, Enumerator, hWndParent, Flags)); } std::list<SP_DEVINFO_DATA> SetupDiCreateDeviceInfoDataList(HDEVINFO DeviceInfoSet) { std::list<SP_DEVINFO_DATA> DevInfoDatas; for (DWORD i = 0; i < std::numeric_limits<DWORD>::max(); i++) { SP_DEVINFO_DATA DevInfoData{ sizeof(SP_DEVINFO_DATA) }; if (!SetupDiEnumDeviceInfo(DeviceInfoSet, i, &DevInfoData)) break; DevInfoDatas.emplace_back(DevInfoData); } return std::move(DevInfoDatas); } BOOL SetupDiGetDeviceRegistryPropertyAsStringW( std::wstring& result, HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Property) { DWORD RequiredSize; DWORD PropertyRegDataType; if (!::SetupDiGetDeviceRegistryPropertyW(DeviceInfoSet, DeviceInfoData, Property, &PropertyRegDataType, nullptr, 0, &RequiredSize) && ::GetLastError() != ERROR_INSUFFICIENT_BUFFER) { return FALSE; } if (PropertyRegDataType != REG_SZ) { ::SetLastError(ERROR_INVALID_DATATYPE); return FALSE; } result.resize(RequiredSize); return ::SetupDiGetDeviceRegistryPropertyW(DeviceInfoSet, DeviceInfoData, Property, nullptr, std::bit_cast<PBYTE>(result.data()), static_cast<DWORD>(result.size()), nullptr); }
クラスに対応するデバイス情報要素の概要を列挙する
#pragma comment(lib, "SetupAPI.lib") #define STRICT #define NOMINMAX #include <Windows.h> #include <SetupAPI.h> #include "Utility.hpp" #include <iostream> #include <set> int main() { std::wcout.imbue(std::locale("", std::locale::ctype)); auto DevInfoHandle{ unique_SetupDiGetClassDevsW( nullptr, nullptr, nullptr, DIGCF_ALLCLASSES) }; std::set<std::wstring> DevClassSet; std::wstring Buffer; // ループ中で繰り返し使用するバッファー for (auto& DevInfoData : SetupDiCreateDeviceInfoDataList(DevInfoHandle.get())) { SetupDiGetDeviceRegistryPropertyAsStringW(Buffer, DevInfoHandle.get(), &DevInfoData, SPDRP_CLASS); DevClassSet.emplace(Buffer.c_str()); } // クラスの列挙 for (const auto& DevClass : DevClassSet) { wcout << DevClass << endl; } }