C++で開発しているのですが、MSNdis_80211_WLanBssIdクラスを用いてNdis80211SsIdとNdis80211Rssiの値を取得することができません。
どなたか、アドバイスをお願いします。
以下、ソースです。
// 接続開始
wbem_locator->ConnectServer(_bstr_t(L"\\\\.\\ROOT\\WMI"),NULL, NULL, 0, NULL,0, 0, &wbem_services);
wbem_services->ExecQuery(bstr_t("WQL"),bstr_t("SELECT * FROM MSNdis_80211_WLanBssId"),WBEM_FLAG_RETURN_IMMEDIATELY |WBEM_FLAG_FORWARD_ONLY , NULL, &wbem_enumerator);
IWbemClassObject *wbem_object;
ULONG returned = 0;
// プロパティ読み込み
while(wbem_enumerator) {
wbem_enumerator->Next(WBEM_INFINITE, 1,&wbem_object, &returned);
if(0 == returned)
break;
_bstr_t property_name[] = {L"Ndis80211SsId", L"Ndis80211Rssi"};
for(int item = 0; item < 1; item++) {
VARIANT property_value;
_bstr_t display_name;
VariantInit(&property_value);
wbem_object->Get(property_name[item], 0,&property_value, 0, 0);
display_name = property_value;
cout << property_name[item] <<" : " << display_name << endl;
VariantClear(&property_value);
}
}
解決まで到達できませんでしたが、とりあえずわかったことだけ書いておきます。
----
cx20さんのコメントにあるwbemtest.exeで探ってみました。
使用するクエリーは
SELECT * FROM MSNDis_80211_BSSIList
で、NICの個数分、MSNDis_80211_BSSIList型のオブジェクトが取得できます。
その個々に対して、
wbem_object->Get(L"Ndis80211BSSIList", 0, &property_value, 0, 0);
とすると、property_value.vtが0x200D(VT_IUNKNOWN|VT_ARRAY)であることが分かります。
つまり、配列(Ndis80211BSSIList)の個々がMSNdis_80211_WLanBssId型であることまではわかりました。
ただ、
VT_IUNKNOWN|VT_ARRAYを配列分解して、QueryInterfaceでIUNKNOWNからMSNdis_80211_WLanBssIdのインターフェースを得て、
なおかつ、Ndis80211SsIdはVT_BYTE|VT_ARRAYであるので、また配列分解して、文字列にして、、、
と、まだまだ先は長そうです。
とりあえず動く。とにかく長い、、
VBScriptなら20Step程度でかけそうだ。
// C ランタイム ヘッダー #include <stdio.h> #include <tchar.h> // Windowsヘッダー #define WIN32_LEAN_AND_MEAN #include <windows.h> // DCOM ヘッダー #define _WIN32_DCOM #include <comutil.h> #pragma comment(lib, "comsupp.lib") #include <wbemidl.h> #pragma comment(lib, "wbemuuid.lib") /********************************************************************* * MSNdis_80211_WLanBssIdオブジェクト処理 ********************************************************************/ int proc_object2(IWbemClassObject* pClassObject) { /*------------------------------------------------------------------* * MSNdis_80211_WLanBssId::Ndis80211SsIdLength取得 *------------------------------------------------------------------*/ VARIANT v; BSTR strClassProp = SysAllocString(L"Ndis80211SsIdLength"); HRESULT hr = pClassObject->Get(strClassProp, 0, &v, 0, 0); SysFreeString(strClassProp); if(FAILED(hr)) { printf("!!!! Error !!!! pClassObject->Get(Ndis80211SsIdLength)\n"); return 1; } /*------------------------------------------------------------------* * MSNdis_80211_WLanBssId::Ndis80211SsIdLengthはLONGか? *------------------------------------------------------------------*/ if(V_VT(&v) != (VT_I4)) { printf("!!!! Error !!!! VARTYPE=%d\n", V_VT(&v)); return 1; } /*------------------------------------------------------------------* * MSNdis_80211_WLanBssId::Ndis80211SsIdLengthは1~32になるはず *------------------------------------------------------------------*/ LONG ssidLen = v.lVal; if(v.lVal < 1 || v.lVal > 32) { printf("!!!! Error !!!! Ndis80211SsIdLength=%d\n", v.lVal); return 0; } printf("\tNdis80211SsIdLength=%d\n", v.lVal); VariantClear(&v); /*------------------------------------------------------------------* * MSNdis_80211_WLanBssId::Ndis80211SsId取得 *------------------------------------------------------------------*/ strClassProp = SysAllocString(L"Ndis80211SsId"); hr = pClassObject->Get(strClassProp, 0, &v, 0, 0); SysFreeString(strClassProp); if(FAILED(hr)) { printf("!!!! Error !!!! pClassObject->Get(Ndis80211SsId)\n"); return 1; } /*------------------------------------------------------------------* * MSNdis_80211_WLanBssId::Ndis80211SsIdはバイト配列か? *------------------------------------------------------------------*/ if(V_VT(&v) != (VT_ARRAY|VT_UI1)) { printf("!!!! Error !!!! VARTYPE=%d\n", V_VT(&v)); return 1; } /*------------------------------------------------------------------* * 配列分解処理を初期化 *------------------------------------------------------------------*/ SAFEARRAY* psa = V_ARRAY(&v); if(!SafeArrayGetDim(psa)) { printf("!!!! Error !!!! SafeArrayGetDim\n"); return 1; } /*------------------------------------------------------------------* * 一元配列か? *------------------------------------------------------------------*/ if (psa->cDims != 1) { printf("!!!! Error !!!! psa->cDims=%d\n", psa->cDims); return 1; } /*------------------------------------------------------------------* * 配列のインデックス下限 *------------------------------------------------------------------*/ LONG lLBound; hr = SafeArrayGetLBound(psa, 1, &lLBound); if (FAILED(hr)) { printf("!!!! Error !!!! SafeArrayGetLBound\n"); return 1; } /*------------------------------------------------------------------* * 配列のインデックス上限 *------------------------------------------------------------------*/ LONG lUBound; hr = SafeArrayGetUBound(psa, 1, &lUBound); if (FAILED(hr)) { printf("!!!! Error !!!! SafeArrayGetUBound\n"); return 1; } byte b[32]; memset(b, NULL, 32); int i; LONG lIndex[1]; for(lIndex[0] = lLBound, i = 0; lIndex[0] <= lUBound; lIndex[0]++, i++) { /*------------------------------------------------------------------* * 配列の要素(BYTE)を取得 *------------------------------------------------------------------*/ BYTE pb = NULL; hr = SafeArrayGetElement(psa, lIndex, &b[i]); if (FAILED(hr)) { printf("!!!! Error !!!! SafeArrayGetElement\n"); return 1; } } printf("\tNdis80211SsId=%s\n", b); VariantClear(&v); /*------------------------------------------------------------------* * MSNdis_80211_WLanBssId::Ndis80211Rssi取得 *------------------------------------------------------------------*/ strClassProp = SysAllocString(L"Ndis80211Rssi"); hr = pClassObject->Get(strClassProp, 0, &v, 0, 0); SysFreeString(strClassProp); if(FAILED(hr)) { printf("!!!! Error !!!! pClassObject->Get(Ndis80211Rssi)\n"); return 1; } /*------------------------------------------------------------------* * MSNdis_80211_WLanBssId::Ndis80211RssiはLONGか? *------------------------------------------------------------------*/ if(V_VT(&v) != (VT_I4)) { printf("!!!! Error !!!! VARTYPE=%d\n", V_VT(&v)); return 1; } printf("\tNdis80211Rssi=%d\n", v.lVal); /*------------------------------------------------------------------* * MSNdis_80211_WLanBssId::Ndis80211Rssi判定 *------------------------------------------------------------------*/ _TCHAR* msg = NULL; if (v.lVal >= 0) msg = "Error"; else if(v.lVal >= -60) msg = "Excellent"; else if(v.lVal >= -70) msg = "Very Good"; else if(v.lVal >= -80) msg = "Good"; else if(v.lVal >= -90) msg = "Low"; else if(v.lVal >= -100) msg = "Very Low"; else msg = "No Signal"; printf("\tNdis80211RssiMessage=%s\n", msg); VariantClear(&v); return 0; } /********************************************************************* * MSNDis_80211_BSSIListオブジェクト処理 ********************************************************************/ int proc_object(IWbemClassObject* pClassObject) { /*------------------------------------------------------------------* * MSNDis_80211_BSSIList::InstanceName取得(NIC名) *------------------------------------------------------------------*/ VARIANT v; BSTR strClassProp = SysAllocString(L"InstanceName"); HRESULT hr = pClassObject->Get(strClassProp, 0, &v, 0, 0); SysFreeString(strClassProp); if(FAILED(hr)) { printf("!!!! Error !!!! pClassObject->Get(InstanceName)\n"); return 1; } printf("InstanceName=%s\n", (_TCHAR*)(_bstr_t)&v); VariantClear(&v); /*------------------------------------------------------------------* * MSNDis_80211_BSSIList::Ndis80211BSSIList取得 *------------------------------------------------------------------*/ strClassProp = SysAllocString(L"Ndis80211BSSIList"); hr = pClassObject->Get(strClassProp, 0, &v, 0, 0); SysFreeString(strClassProp); if(FAILED(hr)) { printf("!!!! Error !!!! pClassObject->Get(Ndis80211BSSIList)\n"); return 1; } /*------------------------------------------------------------------* * MSNDis_80211_BSSIList::Ndis80211BSSIListはオブジェクトの配列か? *------------------------------------------------------------------*/ if(V_VT(&v) != (VT_ARRAY|VT_UNKNOWN)) { printf("!!!! Error !!!! VARTYPE=%d\n", V_VT(&v)); return 1; } /*------------------------------------------------------------------* * 配列分解処理を初期化 *------------------------------------------------------------------*/ SAFEARRAY* psa = V_ARRAY(&v); if(!SafeArrayGetDim(psa)) { printf("!!!! Error !!!! SafeArrayGetDim\n"); return 1; } /*------------------------------------------------------------------* * 一元配列か? *------------------------------------------------------------------*/ if (psa->cDims != 1) { printf("!!!! Error !!!! psa->cDims=%d\n", psa->cDims); return 1; } /*------------------------------------------------------------------* * 配列のインデックス下限 *------------------------------------------------------------------*/ LONG lLBound; hr = SafeArrayGetLBound(psa, 1, &lLBound); if (FAILED(hr)) { printf("!!!! Error !!!! SafeArrayGetLBound\n"); return 1; } /*------------------------------------------------------------------* * 配列のインデックス上限 *------------------------------------------------------------------*/ LONG lUBound; hr = SafeArrayGetUBound(psa, 1, &lUBound); if (FAILED(hr)) { printf("!!!! Error !!!! SafeArrayGetUBound\n"); return 1; } /*------------------------------------------------------------------* * 配列の要素数(MSNdis_80211_WLanBssIdオブジェクトの個数) *------------------------------------------------------------------*/ printf("Ndis80211BSSIList Count=%d\n----------\n", lUBound-lLBound + 1); LONG lIndex[1]; for(lIndex[0] = lLBound; lIndex[0] <= lUBound; lIndex[0]++) { /*------------------------------------------------------------------* * 配列の要素インデックス *------------------------------------------------------------------*/ printf("Ndis80211BSSIList(%d)\n", lIndex[0]); /*------------------------------------------------------------------* * 配列の要素(MSNdis_80211_WLanBssId)を取得 *------------------------------------------------------------------*/ IWbemClassObject* pClassObject2 = NULL; hr = SafeArrayGetElement(psa, lIndex, &pClassObject2); if (FAILED(hr)) { printf("!!!! Error !!!! SafeArrayGetElement\n"); return 1; } /*------------------------------------------------------------------* * MSNdis_80211_WLanBssIdオブジェクト処理 *------------------------------------------------------------------*/ if(proc_object2(pClassObject2) != 0) { return 1; } /*------------------------------------------------------------------* * MSNdis_80211_WLanBssIdオブジェクト開放 *------------------------------------------------------------------*/ pClassObject2->Release(); printf("----------\n"); } VariantClear(&v); return 0; } /********************************************************************* * WMIクエリ結果列挙 ********************************************************************/ int proc_enum(IEnumWbemClassObject* pEnumObject) { /*------------------------------------------------------------------* * WMIクエリ結果列挙 *------------------------------------------------------------------*/ HRESULT hr = pEnumObject->Reset(); while(true) { /*------------------------------------------------------------------* * MSNDis_80211_BSSIListオブジェクト取得(クエリ結果) *------------------------------------------------------------------*/ ULONG uCount = 1, uReturned; IWbemClassObject* pClassObject = NULL; hr = pEnumObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned); if(FAILED(hr)) { printf("!!!! Error !!!! pEnumObject->Next\n"); return 1; } /*------------------------------------------------------------------* * クエリ結果終了? *------------------------------------------------------------------*/ if(uReturned == 0) break; /*------------------------------------------------------------------* * MSNDis_80211_BSSIListオブジェクト処理 *------------------------------------------------------------------*/ if(proc_object(pClassObject) != 0) { return 1; } /*------------------------------------------------------------------* * MSNDis_80211_BSSIListオブジェクト開放 *------------------------------------------------------------------*/ pClassObject->Release(); } return 0; } /********************************************************************* * クエリ処理 ********************************************************************/ int proc_query(IWbemServices* pWbemServices) { /*------------------------------------------------------------------* * WMIクエリ発行 *------------------------------------------------------------------*/ IEnumWbemClassObject* pEnumObject = NULL; HRESULT hr = pWbemServices->ExecQuery( L"WQL", L"SELECT * FROM MSNDis_80211_BSSIList", WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumObject ); /*------------------------------------------------------------------* * WMIクエリ結果列挙 *------------------------------------------------------------------*/ if(proc_enum(pEnumObject) != 0) { return 1; } /*------------------------------------------------------------------* * WMIクエリ結果開放 *------------------------------------------------------------------*/ pEnumObject->Release(); return 0; } /********************************************************************* * WMI処理 ********************************************************************/ int proc_wmi(IWbemLocator* pIWbemLocator) { /*------------------------------------------------------------------* * WMI初期化 *------------------------------------------------------------------*/ IWbemServices* pWbemServices = NULL; HRESULT hr = pIWbemLocator->ConnectServer( L"root\\wmi", NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices ); if(FAILED(hr)) { printf("!!!! Error !!!! pIWbemLocator->ConnectServer\n"); return 1; } /*------------------------------------------------------------------* * クエリ処理 *------------------------------------------------------------------*/ if(proc_query(pWbemServices) != 0) { return 1; } /*------------------------------------------------------------------* * WMI開放 *------------------------------------------------------------------*/ pWbemServices->Release(); return 0; } /********************************************************************* * COM処理 ********************************************************************/ int proc_com() { /*------------------------------------------------------------------* * COM取得 *------------------------------------------------------------------*/ IWbemLocator* pIWbemLocator = NULL; HRESULT hr = CoCreateInstance( CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pIWbemLocator ); if(FAILED(hr)) { printf("!!!! Error !!!! CoCreateInstance\n"); return 1; } /*------------------------------------------------------------------* * WMI処理 *------------------------------------------------------------------*/ if(proc_wmi(pIWbemLocator) != 0) { return 1; } /*------------------------------------------------------------------* * COM開放 *------------------------------------------------------------------*/ pIWbemLocator->Release(); return 0; } /********************************************************************* * メイン ********************************************************************/ int _tmain(int argc, _TCHAR* argv[]) { /*------------------------------------------------------------------* * COM初期化 *------------------------------------------------------------------*/ HRESULT hr = CoInitializeEx(0, COINIT_MULTITHREADED); if (FAILED(hr)) { printf("!!!! Error !!!! CoInitializeEx\n"); return 1; } /*------------------------------------------------------------------* * COMアクセス定義 *------------------------------------------------------------------*/ hr = CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL ); if (FAILED(hr)) { printf("!!!! Error !!!! CoInitializeSecurity\n"); return 1; } /*------------------------------------------------------------------* * COM処理 *------------------------------------------------------------------*/ if(proc_com() != 0) { return 1; } /*------------------------------------------------------------------* * COM開放 *------------------------------------------------------------------*/ CoUninitialize(); return 0; }
コメント(1件)
値の取得ができないというのは VBScript 等では取得できるが、C++ では取得できないということでしょうか?
VBScript 等でも取得できないということであれば、そもそも値がセットされていない(オブジェクトがNULL)ということになります。
WMI の情報を取得する方法は色々あるかと思いますが、
OS 標準の「WMI Tester (wbemtest.exe)」というツールで確認できますので、
試してみてはいかがでしょうか?
<参考情報>
■ サンプルプログラム集 WMIイントロダクション
http://homepage2.nifty.com/Mr_XRAY/Delphi/plSamples/A_WMI_Introduction.htm
すでに確認済みでしたら、すみません。