C++ 获取监视器的设备信息集:返回的句柄总是无效的\u句柄\u值
我正在尝试列出当前连接到计算机的所有监视器的设备信息。我有一个函数可以做到这一点,它的90%都完成了,除非我使用第二个参数集(非空)调用函数C++ 获取监视器的设备信息集:返回的句柄总是无效的\u句柄\u值,c++,winapi,device,guid,C++,Winapi,Device,Guid,我正在尝试列出当前连接到计算机的所有监视器的设备信息。我有一个函数可以做到这一点,它的90%都完成了,除非我使用第二个参数集(非空)调用函数SetupDiGetClassDevs(),然后函数总是失败(返回无效的句柄值) 当我调用GetLastError()时,我得到了错误13(十进制),即,“数据无效”,我不确定这是什么意思 出了什么问题?您能就发生了什么以及我如何解决它提供一些建议吗? My函数,尝试仅获取监视器的设备信息集,并输出每个监视器的详细信息(错误行已注释): void prin
SetupDiGetClassDevs()
,然后函数总是失败(返回无效的句柄值)
当我调用GetLastError()
时,我得到了错误13(十进制),即,“数据无效”
,我不确定这是什么意思
出了什么问题?您能就发生了什么以及我如何解决它提供一些建议吗?
My函数,尝试仅获取监视器的设备信息集,并输出每个监视器的详细信息(错误行已注释):
void printDeviceData(GUID)
{
//设备类别:http://msdn.microsoft.com/en-us/library/windows/hardware/ff553426
//系统设备类别:http://msdn.microsoft.com/en-us/library/windows/hardware/ff553428
//监控类GUI:{4d36e96e-e325-11ce-bfc1-08002be10318}
DWORD dataT=0;
PCTSTR监视器GUID=\u T(“”);
SP_DEVINFO_DATA deviceinfo={0};
DeviceInfo DATA.cbSize=sizeof(SP_DEVINFO_数据);
DeviceInfo.ClassGuid=guID;
//步骤1:仅获取监视器的设备信息集
//此处发生错误:SetupDiGetClassDevs()始终失败
//还尝试了参数2的这些值:“监视器”“PCI”,但都会导致函数返回无效的\u句柄\u值
HDEVINFO HDEVINFO=SetupDiGetClassDevs(&guID,_T(“{4d36e96e-e325-11ce-bfc1-08002be10318}”),NULL,DIGCF|u PRESENT | DIGCF|u DEVICEINTERFACE);
if(hDevInfo==无效的句柄值){
//outputLastError(失败1);
printf(“hDevInfo==无效的\u句柄\u值”);
返回;
}
else printf(“成功1\n”);
if(SetupDiGetSelectedDevice(hDevInfo,&DeviceInfo数据)==FALSE){
//outputLastError(_T(“SetupDiGetSelectedDevice(hDevInfo,&DeviceInfo数据)==FALSE”);
printf(“SetupDiGetSelectedDevice(hDevInfo,&DeviceInfo)==FALSE,%d,%x\n”,GetLastError(),GetLastError());
返回;
}
else printf(“成功2\n”);
//步骤2:对于每个监视器:输出设备信息
const unsigned int FLAG_NUM=30;
DWORD标志[]={SPDRP_FRIENDLYNAME,SPDRP_枚举器_NAME,SPDRP_物理_设备_对象_NAME,SPDRP_DEVICEDESC,
SPDRP_地址、SPDRP_总线号、SPDRP_总线型GUID、SPDRP_特性、SPDRP_类、SPDRP_类GUID、,
SPDRP_兼容EIDS、SPDRP_配置标志、SPDRP_设备、电源数据、SPDRP_开发类型、SPDRP_驱动程序、,
SPDRP_枚举器_名称、SPDRP_独占、SPDRP_硬件ID、SPDRP_安装_状态、SPDRP_LEGACYBUSTYPE、,
SPDRP_位置信息、SPDRP_位置路径、SPDRP_下部过滤器、SPDRP_制造商、,
SPDRP_物理_设备_对象_名称、SPDRP_用户界面_编号、SPDRP_用户界面_编号描述格式、SPDRP_上层过滤器、,
SPDRP_安全性_SDS、SPDRP_安全性、SPDRP_服务};
对于(inti=0;i,根据文档,枚举数必须设置为有效的设备实例ID,根据必须这样指定
“PCI\VEN_1000&DEV_0001&SUBSYS\u00000000&REV_02\1&08”
我还没有测试它,但我认为这就是无效数据的来源
HDEVINFO SetupDiGetClassDevs(
_In_opt_ const GUID *ClassGuid,
_In_opt_ PCTSTR Enumerator, // According to MSDN this param MUST be set if I want Device Information for a specific class(Monitors)
_In_opt_ HWND hwndParent,
_In_ DWORD Flags
);
void printDeviceData(GUID guID)
{
// Device Classes: http://msdn.microsoft.com/en-us/library/windows/hardware/ff553426
// System Device Classes: http://msdn.microsoft.com/en-us/library/windows/hardware/ff553428
// Monitor Class GUI: {4d36e96e-e325-11ce-bfc1-08002be10318}
DWORD dataT = 0;
PCTSTR monitorGuID = _T("");
SP_DEVINFO_DATA deviceInfoData = {0};
deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
deviceInfoData.ClassGuid = guID;
// Step 1: Get Device Information Set for Monitors only
// ERROR OCCURS HERE: SetupDiGetClassDevs() always fails
// Also tried these values for param 2: "Monitor" "PCI" but all cause the function to return INVALID_HANDLE_VALUE
HDEVINFO hDevInfo = SetupDiGetClassDevs(&guID, _T("{4d36e96e-e325-11ce-bfc1-08002be10318}"), NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (hDevInfo == INVALID_HANDLE_VALUE) {
//outputLastError(_T("Fail 1"));
printf("hDevInfo == INVALID_HANDLE_VALUE\n");
return;
}
else printf("SUCCESS 1\n");
if (SetupDiGetSelectedDevice(hDevInfo, &deviceInfoData) == FALSE) {
//outputLastError(_T("SetupDiGetSelectedDevice(hDevInfo, &deviceInfoData) == FALSE"));
printf("SetupDiGetSelectedDevice(hDevInfo, &deviceInfoData) == FALSE, %d, %x\n", GetLastError(), GetLastError());
return;
}
else printf("SUCCESS 2\n");
// Step 2: For each Monitor: Output Device information
const unsigned int FLAG_NUM = 30;
DWORD flags[] = {SPDRP_FRIENDLYNAME, SPDRP_ENUMERATOR_NAME, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME, SPDRP_DEVICEDESC,
SPDRP_ADDRESS, SPDRP_BUSNUMBER, SPDRP_BUSTYPEGUID, SPDRP_CHARACTERISTICS, SPDRP_CLASS, SPDRP_CLASSGUID,
SPDRP_COMPATIBLEIDS, SPDRP_CONFIGFLAGS, SPDRP_DEVICE_POWER_DATA, SPDRP_DEVTYPE, SPDRP_DRIVER,
SPDRP_ENUMERATOR_NAME, SPDRP_EXCLUSIVE, SPDRP_HARDWAREID, SPDRP_INSTALL_STATE, SPDRP_LEGACYBUSTYPE,
SPDRP_LOCATION_INFORMATION, SPDRP_LOCATION_PATHS, SPDRP_LOWERFILTERS, SPDRP_MFG,
SPDRP_PHYSICAL_DEVICE_OBJECT_NAME, SPDRP_UI_NUMBER, SPDRP_UI_NUMBER_DESC_FORMAT, SPDRP_UPPERFILTERS,
SPDRP_SECURITY_SDS, SPDRP_SECURITY, SPDRP_SERVICE };
for (int i=0; i<=FLAG_NUM; i++) {
DWORD buffersize = 0;
LPTSTR buffer = NULL;
while (!SetupDiGetDeviceRegistryProperty(hDevInfo, &deviceInfoData, flags[i], &dataT,
(PBYTE)buffer, buffersize, &buffersize))
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Change the buffer size.
if (buffer)
LocalFree(buffer);
buffer = (LPTSTR)LocalAlloc(LPTR, buffersize);
}
else {
// Insert error handling here.
break;
}
}
printf("Data: %d: %s\n", i, buffer);
if (buffer)
LocalFree(buffer);
}
SetupDiDestroyDeviceInfoList(hDevInfo);
}