Используя диспетчер устройств, пользователь может явно включить / отключить устройство, как показано на следующем рисунке.
Для данного устройства я хочу знать, находится ли оно в данный момент в состоянии отключенного / включенного пользователя.
Я попробовал следующие подходы
CM_Get_DevNode_Status(&status, &problem, data.DevInst, 0);
Я надеялся, что присутствие DN_STARTED
, или же DN_DRIVER_LOADED
сказал бы мне это. Но они могут быть нулевыми, даже если драйвер загружается / выгружается ОС, когда устройство подключается / отключается. Например, устройство, которое включено и для которого загружен драйвер. DN_STARTED
будет 1
, но когда мы отключаем устройство, оно устанавливается в ноль, прежде чем запись устройства удаляется из диспетчера устройств.SetupDiGetDeviceRegistryProperty(..., SPDRP_INSTALL_STATE, ...)
Я, хотя состояние CM_INSTALL_STATE_INSTALLED
должно означать, что устройство включено. Но функция возвращает это состояние даже для отключенных устройств.Используя WMI, я смог получить необходимую информацию, но я использовал wmi в PowerShell. Я не хочу использовать wmi, так как это довольно сложно реализовать на нативном c ++. Я использовал следующий запрос.
Select Name, Availability, ConfigManagerErrorCode, ConfigManagerUserConfig from Win32_PnPEntity where Name = 'NVIDIA Quadro M1000M'
ConfigManagerErrorCode в приведенном выше запросе, если установлено значение 22, означает, что устройство было отключено, 21 означает, что Windows удаляет устройство
Я ищу решение не WMI.
Информация может быть получена из кода проблемы устройства. Есть два способа, которые я мог бы найти, чтобы получить это.
SetupDiGetDeviceProperty()
запросить DEVPKEY_Device_ProblemCode
,CM_Get_DevNode_Status()
код проблемы будет присутствовать во втором аргументе после вызова.Код проблемы 22 (CM_PROB_DISABLED
) означает, что устройство было явно отключено пользователем с помощью диспетчера устройств или другой подобной утилиты.
Образец кода
#include "stdafx.h"#include <Windows.h>
#include <SetupAPI.h>
#include <Cfgmgr32.h>
#include <devguid.h>
#include <initguid.h>
#include "devpkey.h"#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
HDEVINFO hDevInfo = ::SetupDiGetClassDevs(&GUID_DEVCLASS_DISPLAY, NULL, NULL, 0); //only getting for GPUs on the machine
if (INVALID_HANDLE_VALUE != hDevInfo)
{
SP_DEVINFO_DATA data;
data.cbSize = (DWORD)sizeof(data);
for (unsigned int nIndex = 0; ::SetupDiEnumDeviceInfo(hDevInfo, nIndex, &data); nIndex++)
{
ULONG status = 0, problem = 0;
CONFIGRET cr = ::CM_Get_DevNode_Status(&status, &problem, data.DevInst, 0); //after the call 'problem' variable will have the problem code
if (CR_SUCCESS == cr)
{
cout << " problem " << problem <<endl;
if(problem == CM_PROB_DISABLED)
{ /*Do Something*/ }
DEVPROPTYPE propertyType;
const DWORD propertyBufferSize = 100;
BYTE propertyBuffer[propertyBufferSize];
std::fill(begin(propertyBuffer), end(propertyBuffer), BYTE(0));
DWORD requiredSize = 0;
if (SetupDiGetDeviceProperty(hDevInfo, &data, &DEVPKEY_Device_ProblemCode, &propertyType, propertyBuffer, propertyBufferSize, &requiredSize, 0)) //after the call 'propertyBuffer' will have error codes
{
unsigned long deviceProblemCode = *((unsigned long*)propertyBuffer);
cout << " deviceProblemCode " << deviceProblemCode << endl;
if(problem == CM_PROB_DISABLED)
{ /*Do Something*/ }
}
}
}
}
return 0;
}
Пример вывода
problem 0
deviceProblemCode 0
problem 22
deviceProblemCode 22
В вопросе видно, что Intel(R) HD Graphics 530
был включен, и NVIDIA Quadro M1000M
был отключен. Следовательно, в выводе мы получили код ошибки 0 и код проблемы 22 (CM_PROB_DISABLED
).
Других решений пока нет …