デバイス情報要素の文字列プロパティ(概要、クラス、クラスGUID、フレンドリーネーム、ハードウェアID)を列挙するコードです。再利用可能なコードをUtility.hpp
へ移動しています。
文字列プロパティ(概要、クラス、クラスGUID、フレンドリーネーム、ハードウェアID)を列挙する
Main.cpp
#include <memory> #include <string> #include <numeric> #include <iostream> #include <tuple> #include <list> #pragma comment(lib, "SetupAPI.lib") #define STRICT #define NOMINMAX #include <Windows.h> #include <SetupAPI.h> #include "Utility.hpp" using namespace std; int main() { wcout.imbue(locale("Japanese", locale::ctype)); auto DevInfoHandle = unique_SetupDiGetClassDevsW( nullptr, nullptr, nullptr, DIGCF_ALLCLASSES); // ループ中で繰り返し使用するバッファーの用意 wstring DevDesc; wstring DevClass; wstring DevClassGuid; wstring DevFriendlyName; wstring DevHardwareId; wcout << L"ClassGuid, DevInst, SPDRP_DEVICEDESC, SPDRP_CLASS, SPDRP_CLASSGUID, SPDRP_FRIENDLYNAME, SPDRP_HARDWAREID" << 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); wcout << guid_to_wstring(DevInfoData.ClassGuid) << L", " << DevInfoData.DevInst << L", " << DevDesc.c_str() << L", " << DevClass.c_str() << L", " << DevClassGuid.c_str() << L", " << DevFriendlyName.c_str() << L", " << DevHardwareId.c_str() << endl; } }
取得したクラスプロパティの値(SPDRP_CLASS
)をunique_SetupDiGetClassDevsW
関数のEnumerator
引数に与えれば取得するデバイス情報要素を制限できます。
Utility.hpp
//----------------------------------------------------------------------------- // Utility.hpp // 再利用可能なコードを定義します。 //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // GUID -> wstring //----------------------------------------------------------------------------- std::wstring guid_to_wstring(const GUID& guid) { LPWSTR s; if (FAILED(::StringFromCLSID(guid, &s))) return {}; std::wstring str = s; ::CoTaskMemFree(s); return std::move(str); } //----------------------------------------------------------------------------- // Setup API wrappers //----------------------------------------------------------------------------- using unique_devinfo_handle = std::unique_ptr<std::remove_pointer_t<HDEVINFO>, decltype(&::SetupDiDestroyDeviceInfoList)>; unique_devinfo_handle make_unique_devinfo_handle(HDEVINFO handle) noexcept { return unique_devinfo_handle(handle, &::SetupDiDestroyDeviceInfoList); } unique_devinfo_handle unique_SetupDiGetClassDevsW( const GUID* ClassGuid, LPCWSTR Enumerator, HWND hWndParent, DWORD Flags) noexcept { return make_unique_devinfo_handle( ::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)) { if (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, reinterpret_cast<PBYTE>(result.data()), result.size(), nullptr); }
クラスを列挙する
Utility.hpp
を使用してクラスを列挙するサンプルコードです。
#include <memory> #include <string> #include <numeric> #include <iostream> #include <tuple> #include <list> #include <set> #pragma comment(lib, "SetupAPI.lib") #define STRICT #define NOMINMAX #include <Windows.h> #include <SetupAPI.h> #include "Utility.hpp" using namespace std; int main() { wcout.imbue(locale("Japanese", locale::ctype)); auto DevInfoHandle = unique_SetupDiGetClassDevsW( nullptr, nullptr, nullptr, DIGCF_ALLCLASSES); set<wstring> DevClassSet; 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; } }
出力例
AudioEndpoint Battery CDROM Computer DiskDrive Display HDC HIDClass Image Keyboard MEDIA Monitor Mouse Net PrintQueue Processor SCSIAdapter SoftwareDevice System USB Volume VolumeSnapshot WPD WSDPrintDevice
クラスに対応するデバイス情報要素の概要を列挙する
Utility.hpp
を使用してクラスに対応するデバイス情報要素の概要を列挙するサンプルコードです。
#include <memory> #include <string> #include <numeric> #include <iostream> #include <tuple> #include <list> #include <map> #include <vector> #pragma comment(lib, "SetupAPI.lib") #define STRICT #define NOMINMAX #include <Windows.h> #include <SetupAPI.h> #include "Utility.hpp" using namespace std; int main() { wcout.imbue(locale("Japanese", locale::ctype)); auto DevInfoHandle = unique_SetupDiGetClassDevsW( nullptr, nullptr, nullptr, DIGCF_ALLCLASSES); map<wstring, vector<wstring>> DevClassMap; wstring DevClassBuffer; wstring DevDescBuffer; for (auto& DevInfoData : SetupDiCreateDeviceInfoDataList(DevInfoHandle.get())) { SetupDiGetDeviceRegistryPropertyAsStringW(DevClassBuffer, DevInfoHandle.get(), &DevInfoData, SPDRP_CLASS); SetupDiGetDeviceRegistryPropertyAsStringW(DevDescBuffer, DevInfoHandle.get(), &DevInfoData, SPDRP_DEVICEDESC); DevClassMap[DevClassBuffer.c_str()].emplace_back(DevDescBuffer.c_str()); } // クラスの列挙 for (const auto& [DevClass, DevDescs] : DevClassMap) { wcout << DevClass << L": "; for (const auto& DevDesc : DevDescs) { wcout << DevDesc << L", "; } wcout << endl << endl; } }