Как узнать, было ли устройство явно отключено пользователем?

Используя диспетчер устройств, пользователь может явно включить / отключить устройство, как показано на следующем рисунке.

введите описание изображения здесь

Для данного устройства я хочу знать, находится ли оно в данный момент в состоянии отключенного / включенного пользователя.

Я попробовал следующие подходы

  1. CM_Get_DevNode_Status(&status, &problem, data.DevInst, 0); Я надеялся, что присутствие DN_STARTED, или же DN_DRIVER_LOADED сказал бы мне это. Но они могут быть нулевыми, даже если драйвер загружается / выгружается ОС, когда устройство подключается / отключается. Например, устройство, которое включено и для которого загружен драйвер. DN_STARTED будет 1, но когда мы отключаем устройство, оно устанавливается в ноль, прежде чем запись устройства удаляется из диспетчера устройств.
  2. SetupDiGetDeviceRegistryProperty(..., SPDRP_INSTALL_STATE, ...) Я, хотя состояние CM_INSTALL_STATE_INSTALLED должно означать, что устройство включено. Но функция возвращает это состояние даже для отключенных устройств.
  3. Используя WMI, я смог получить необходимую информацию, но я использовал wmi в PowerShell. Я не хочу использовать wmi, так как это довольно сложно реализовать на нативном c ++. Я использовал следующий запрос.

    Select Name, Availability, ConfigManagerErrorCode, ConfigManagerUserConfig from Win32_PnPEntity where Name = 'NVIDIA Quadro M1000M'

ConfigManagerErrorCode в приведенном выше запросе, если установлено значение 22, означает, что устройство было отключено, 21 означает, что Windows удаляет устройство

Я ищу решение не WMI.

5

Решение

Информация может быть получена из кода проблемы устройства. Есть два способа, которые я мог бы найти, чтобы получить это.

  1. использование SetupDiGetDeviceProperty() запросить DEVPKEY_Device_ProblemCode,
  2. использование 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).

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]