偵測Windows系統裝置管理員中有黃色驚嘆號的裝置名稱

更新 發佈閱讀 1 分鐘


說實在的,過去一兩年來,每天客戶都跟我抱怨﹔你那個甚麼爛系統,總是有裝置遺失的問題! 小弟實在不堪其擾,因為裝置管理員黃色驚嘆號的產生,也不一定真的是我們的問題,也常常是第三方周邊裝置不給力呀!


當Windows無法正確偵測周邊裝置狀態的時候,就會在裝置管理員該周邊的圖示上顯示一個黃色驚嘆號,英文就是Yellow Bang或是簡稱YB,表示該周邊的驅動程式安裝不完全或是處於無法正常工作的狀態。


由於這種周邊裝置不正常的狀態常常都是在壓力測試下才會發生,例如不斷地重開機、進出Modern Standby S3或是S4休眠狀態的時候,測試個幾千次才發生個幾次,這種狀況不太可能用人工的方式去檢查周邊裝置狀態,所以我們需要一個小程式,每次開機或是進出休眠狀態的時候去檢查,如果發生黃色驚嘆號,就離開壓力測試迴圈,並且回報那個裝置有問題。


在這邊我們透過WMI API才查詢系統周邊的狀況,其中主要就是呼叫IWbemServices 介面來存取 WMI 服務。透過Win32_PnPEntity類別,找出任何一個裝置的ConfigManagerErrorCode不等於0,如果不等於0,就表示該裝置處於不正常的狀態。


詳細的程式碼如下,提供大家做為參考。

//
// 使用WMI API來列出所有在裝置管理員中有黃色驚嘆號的裝置名稱。
//
#include <iostream>
#include <wbemidl.h>
#pragma comment(lib, "wbemuuid.lib")
#include <comdef.h>
#include <ctime>

using namespace std;

int main(int argc, char** argv)
{
HRESULT hres;

// Initialize COM.
hres = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hres))
{
cout << "Failed to initialize COM library. Error code = 0x"
<< hex << hres << endl;
return 1;
}

// Set general COM security levels.
hres = CoInitializeSecurity(
NULL,
-1,
NULL,
NULL,
RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE,
NULL);
if (FAILED(hres))
{
cout << "Failed to initialize security. Error code = 0x"
<< hex << hres << endl;
CoUninitialize();
return 1;
}

// Obtain the initial locator to WMI.
IWbemLocator* pLoc = NULL;
hres = CoCreateInstance(
CLSID_WbemLocator,
0,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator,
(LPVOID*)&pLoc);
if (FAILED(hres))
{
cout << "Failed to create IWbemLocator object. "
<< "Error code = 0x"
<< hex << hres << endl;
CoUninitialize();
return 1;
}

// Connect to WMI through the IWbemLocator::ConnectServer method.
IWbemServices* pSvc = NULL;
hres = pLoc->ConnectServer(
_bstr_t(L"ROOT\\CIMV2"),
NULL,
NULL,
0,
NULL,
0,
0,
&pSvc);
if (FAILED(hres))
{
cout << "Could not connect. Error code = 0x"
<< hex << hres << endl;
pLoc->Release();
CoUninitialize();
return 1;
}

// Set the IWbemServices proxy so that impersonation
// of the user (client) occurs.
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);
if (FAILED(hres))
{
cout << "Could not set proxy blanket. Error code = 0x"
<< hex << hres << endl;
pSvc->Release();
pLoc->Release();
CoUninitialize();
return 1;
}

// Use the IWbemServices pointer to make requests of WMI.
IEnumWbemClassObject* pEnumerator = NULL;
hres = pSvc->ExecQuery(
bstr_t("WQL"),
bstr_t("SELECT * FROM Win32_PnPEntity WHERE ConfigManagerErrorCode <> 0"),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator);
if (FAILED(hres))
{
cout << "Query for operating system name failed."
<< " Error code = 0x"
<< hex << hres << endl;
pSvc->Release();
pLoc->Release();
CoUninitialize();
return 1;
}

time_t current_time;
char c_time_string[20];

/* Get the current time. */
current_time = time(NULL);

/* Convert it to local time representation. */
strftime(c_time_string, sizeof(c_time_string), "%m/%d %H:%M:%S", localtime(&current_time));

// Get the data from the query.
IWbemClassObject* pclsObj = NULL;
ULONG uReturn = 0;
while (pEnumerator)
{
HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
if (0 == uReturn)
{
wcout << c_time_string << " All device drivers are working fine!" << endl;
break;
}

VARIANT vtProp;
VariantInit(&vtProp);
//hr = pclsObj->Get(L"PNPDeviceID", 0, &vtProp, 0, 0);
//wcout << "PNP Device ID : " << vtProp.bstrVal << endl;
//VariantClear(&vtProp);

hr = pclsObj->Get(L"DeviceID", 0, &vtProp, 0, 0);
wcout << c_time_string << " Device ID : " << vtProp.bstrVal << endl;
VariantClear(&vtProp);

hr = pclsObj->Get(L"Name", 0, &vtProp, 0, 0);
wcout << c_time_string << " Device Name : " << vtProp.bstrVal << endl;
VariantClear(&vtProp);

pclsObj->Release();
}

// Cleanup.
pSvc->Release();
pLoc->Release();
pEnumerator->Release();
CoUninitialize();

return 0;
}


需要注意的是,無論重新開機或是從休眠模式喚醒的情況下,Windows都需要一段時間重新偵測周邊裝置,所以我們必須要等待一段時間之後,再詢問周邊裝置的狀態,而不是立刻執行詢問狀態。這個時間會依據周邊裝置不同,而有所不同,特別是系統忙碌的狀況下,有些USB裝置,甚至會偵測個好幾十秒,都不一定有回應,所以我們建議等個兩三分鐘之後,再開始詢問。


至於重新開機與休眠模式壓力測試的工具,大部分人都是使用微軟所提供的pwrtest的工具,在這邊就不贅述。希望大家都能輕鬆通過系統壓力測試。

留言
avatar-img
留言分享你的想法!
avatar-img
Gary Hu的沙龍
4會員
11內容數
Gary Hu的沙龍的其他內容
2024/12/21
小弟走跳江湖多年,也累績了一些職場心得,在年底轉職熱門時刻,希望能夠幫助到一些有緣人。
2024/12/21
小弟走跳江湖多年,也累績了一些職場心得,在年底轉職熱門時刻,希望能夠幫助到一些有緣人。
2024/10/13
本地端生成式AI工具LM Studio安裝介紹,包含如何手動載入AI模型的技巧。
Thumbnail
2024/10/13
本地端生成式AI工具LM Studio安裝介紹,包含如何手動載入AI模型的技巧。
Thumbnail
看更多
你可能也想看
Thumbnail
還在煩惱平凡日常該如何增添一點小驚喜嗎?全家便利商店這次聯手超萌的馬來貘,推出黑白配色的馬來貘雪糕,不僅外觀吸睛,層次豐富的雙層口味更是讓人一口接一口!本文將帶你探索馬來貘雪糕的多種創意吃法,從簡單的豆漿燕麥碗、藍莓果昔,到大人系的奇亞籽布丁下午茶,讓可愛的馬來貘陪你度過每一餐,增添生活中的小確幸!
Thumbnail
還在煩惱平凡日常該如何增添一點小驚喜嗎?全家便利商店這次聯手超萌的馬來貘,推出黑白配色的馬來貘雪糕,不僅外觀吸睛,層次豐富的雙層口味更是讓人一口接一口!本文將帶你探索馬來貘雪糕的多種創意吃法,從簡單的豆漿燕麥碗、藍莓果昔,到大人系的奇亞籽布丁下午茶,讓可愛的馬來貘陪你度過每一餐,增添生活中的小確幸!
Thumbnail
本文詳細介紹Windows cmd指令的應用,並提供了例說明及追加說明,用戶可以學習如何使用cmd指令對檔案進行處理、選取所需的內容,以及擴展運用到其他類型的檔案,最後還介紹了cmd設計完成後的應用和自動化執行方式。
Thumbnail
本文詳細介紹Windows cmd指令的應用,並提供了例說明及追加說明,用戶可以學習如何使用cmd指令對檔案進行處理、選取所需的內容,以及擴展運用到其他類型的檔案,最後還介紹了cmd設計完成後的應用和自動化執行方式。
Thumbnail
AWS Systems Manager 建立 Activations Windows 使用PowerShell [System.Net.ServicePointManager]::SecurityProtocol = 'TLS12' $code = "activation-code
Thumbnail
AWS Systems Manager 建立 Activations Windows 使用PowerShell [System.Net.ServicePointManager]::SecurityProtocol = 'TLS12' $code = "activation-code
Thumbnail
在 Windows 中,一般是透過應用程式介面刪除應用程式,但有時候會因為用多了 linux 系統而習慣自己手動刪除應用程式 🤣,但在 windows 系統這樣操作的話會出現一個小問題 -> 就是明明應用程式已經不在了,但是在「已安裝的應用程式」的清單中卻還能看到它,這篇就來教大家如何將它們刪除
Thumbnail
在 Windows 中,一般是透過應用程式介面刪除應用程式,但有時候會因為用多了 linux 系統而習慣自己手動刪除應用程式 🤣,但在 windows 系統這樣操作的話會出現一個小問題 -> 就是明明應用程式已經不在了,但是在「已安裝的應用程式」的清單中卻還能看到它,這篇就來教大家如何將它們刪除
Thumbnail
整合測試的時候突然遇到一個突然無法登入產品網站的問題,把程式模組單獨拉出來測試又正常,觀察測試報告後發現出現發生登入異常的時間點並不固定,而且只要發生就會連續發生一段時間,程式被中斷掉。後來確認問題在...
Thumbnail
整合測試的時候突然遇到一個突然無法登入產品網站的問題,把程式模組單獨拉出來測試又正常,觀察測試報告後發現出現發生登入異常的時間點並不固定,而且只要發生就會連續發生一段時間,程式被中斷掉。後來確認問題在...
Thumbnail
打開 PowerShell 關閉wsl  wsl --shutdown 執行: Set-ExecutionPolicy RemoteSigned -Scope CurrentUser iwr -useb https://raw.githubusercontent.com/okibcn/wslc
Thumbnail
打開 PowerShell 關閉wsl  wsl --shutdown 執行: Set-ExecutionPolicy RemoteSigned -Scope CurrentUser iwr -useb https://raw.githubusercontent.com/okibcn/wslc
Thumbnail
ping 指令用於排除網路連線故障,但當你遇到無法時候時?不要慌,這裡有解決方法,錯誤的原因通常有這些: 未安裝 ping 程式 $PATH 環境變數中未設定 ping命令損壞 未使用 sudo 權限存取該指令 我們可以透過一些方法簡單的檢測並且解決,例如我們可以先驗證命令可用性: wh
Thumbnail
ping 指令用於排除網路連線故障,但當你遇到無法時候時?不要慌,這裡有解決方法,錯誤的原因通常有這些: 未安裝 ping 程式 $PATH 環境變數中未設定 ping命令損壞 未使用 sudo 權限存取該指令 我們可以透過一些方法簡單的檢測並且解決,例如我們可以先驗證命令可用性: wh
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News