如何在设备管理器 Windows 中获取带有黄色感叹号的设备列表 - c++

Posted

技术标签:

【中文标题】如何在设备管理器 Windows 中获取带有黄色感叹号的设备列表 - c++【英文标题】:How to get list of devices with yellow exclamation mark in Device Manager Windows - c++ 【发布时间】:2012-02-17 08:48:15 【问题描述】:

我正在使用 msdn WMI 示例代码来获取设备管理器中显示的设备列表,并带有黄色感叹号,但它只正确返回了所有设备的列表 机器上安装的设备。这里的任何人都可以帮助我仅使用 c++ 解决这个问题。 谢谢

    void GetUnKnownDeviceList()

    HRESULT hres;
    hres =  CoInitializeEx(0, COINIT_MULTITHREADED); 

    hres =  CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT,
                                 RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL); 

    IWbemLocator *pLoc = 0;
    hres = CoCreateInstance( CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc);
    IWbemServices *pSvc = 0;                  

    hres = pLoc->ConnectServer(_bstr_t(L"ROOT\\CIMV2"),NULL,NULL,0,NULL,0,0,&pSvc);

    hres = CoSetProxyBlanket(pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE,  NULL, RPC_C_AUTHN_LEVEL_CALL,
                             RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);       

    IEnumWbemClassObject* pEnumerator = NULL;    
    hres = pSvc->ExecQuery(
            bstr_t("WQL"), 
            // bstr_t("SELECT * FROM Win32_PnPEntity"), DOES NOT LIST DEVICES SHOWING WITH YELLOW EXCLAMATION MARK
            bstr_t("SELECT * FROM Win32_PnPEntity WHERE ConfigManagerErrorCode = 0"), // LIST ONLY PROPERLY INSTALLED DEVICES
            WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
            NULL,
            &pEnumerator);

    IWbemClassObject *pclsObj;
    ULONG uReturn = 0;
    while(1)
    
        HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
        VARIANT vtProp;
        hr = pclsObj->Get(L"Name", 0, &vtProp, 0, 0);
        TRACE("Device Name : %s\r\n\", vtProp.bstrVal);
        VariantClear(&vtProp);
        pclsObj->Release();
       


【问题讨论】:

【参考方案1】:

要列出不工作的设备,您需要查询所有 ConfigManagerErrorCode 不是 0 的设备,您必须将 WQL 语句修改为。

SELECT * FROM Win32_PnPEntity WHERE ConfigManagerErrorCode <> 0

【讨论】:

感谢您的回复,在将 WQL 语句修改为您建议的内容后,我在下面的函数 HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1 , &pclsObj, &uReturn); 而不是while(1) 使用while(pEnumerator) 还是一样,我在循环中放了一个断点,循环内的函数 pEnumerator->Next(..) 返回错误。 pEnumerator 是有效的指针,但我检查过。 不,我也从该代码中得到相同的错误 hr=1,pclsobj=NULL 和 uReturn=0
 HRESULT hr = pEnumerator-&gt;Next(WBEM_INFINITE, 1, &amp;pclsObj, &amp;u返回);您提到的代码示例之间的唯一区别是这个函数 hres = pLoc-&gt;ConnectServer(_bstr_t(L"\\\\.\\root\\CIMV2"),...) 和我使用的是 pLoc-&gt; ConnectServer(_bstr_t(L"ROOT\\CIMV2"),...);啊啊啊好郁闷……
我有一个解决办法。一旦我得到通过我上面的代码工作的设备列表。我使用以下功能进行了另一次搜索,然后比较列表和不匹配的设备是在设备管理器中显示为黄色感叹号的设备。不过感谢 RRUZ 的帮助。 While(!SetupDiGetDeviceRegistryProperty(hDevInfo,&DeviceInfoData,SPDRP_DEVICEDESC,&DataT,(PBYTE)buffer,buffersize,&buffersize)) CString csThisDevice = CString(buffer); TRACE ("找到的设备: %s\n", csThisDevice); 【参考方案2】:

您为什么不尝试使用 setupapi 呢?我认为您应该能够用它枚举已知和未知设备的设备节点列表。

【讨论】:

setupapi 函数给出 error=13,即当使用 SPDRP_INSTALL_STATE 选项调用以下函数时未知设备的“数据无效”,该选项不正确且与msdn 文档。但是,该函数确实为 KNOWN 设备返回正确的值。 SetupDiGetDeviceRegistryProperty(hDevInfo,&DeviceInfoData,SPDRP_INSTALL_STATE,...)【参考方案3】:

这个例子可以在 c# 中使用 wmi:

/ Query the device list trough the WMI. If you want to get
// all the properties listen in the MSDN article mentioned
// below, use "select * from Win32_PnPEntity" instead!
ManagementObjectSearcher deviceList =
new ManagementObjectSearcher("Select Name, Status from Win32_PnPEntity");

// Any results? There should be!
if ( deviceList != null )
// Enumerate the devices
foreach ( ManagementObject device in deviceList.Get() )

    // To make the example more simple,
    string name = device.GetPropertyValue("Name").ToString();
    string status = device.GetPropertyValue("Status").ToString();

    // Uncomment these lines and use the "select * query" if you 
    // want a VERY verbose list
    // foreach (PropertyData prop in device.Properties)
    //    Console.WriteLine( "\t" + prop.Name + ": " + prop.Value);

    // More details on the valid properties:
    // http://msdn.microsoft.com/en-us/library/aa394353(VS.85).aspx
    Console.WriteLine( "Device name: 0", name );  
    Console.WriteLine( "\tStatus: 0", status );

    // Part II, Evaluate the device status.
    bool working = (( status == "OK" ) || ( status == "Degraded" )
        || ( status == "Pred Fail" ));

    Console.WriteLine( "\tWorking?: 0", working );

http://www.codeproject.com/Articles/30031/Query-hardware-device-status-in-C

只需更改状态或 ConfigManagerErrorCode 即可获得您要查找的错误类型。

【讨论】:

以上是关于如何在设备管理器 Windows 中获取带有黄色感叹号的设备列表 - c++的主要内容,如果未能解决你的问题,请参考以下文章

关于admin-pc 我的是win7系统,今天打开设备和打印机,发现设备里有一个ADMIN-PC,还带有黄色感叹号

如何像在 Windows 资源管理器中一样在 Delphi 中获取排序顺序?

在设备管理器中处理器出现黄色感叹号是啥意思啊

带有WPF的Aero玻璃框架上类似Windows资源管理器的搜索框

如何从 Windows 任务管理器(应用程序选项卡)获取应用程序 + 从 Delphi 获取它们在 HDD 上的位置

带有 WPF 的 Aero 玻璃框架上类似于 Windows 资源管理器的搜索框