Windows Management Instrumentation (2)
WmiCallの処理結果をAPIネイティブの結果(IEnumWbemClassObject)ではなく、WmiResultクラスに格納するように修正しました。
wmi.hの定義で
IEnumWbemClassObject *access(String select_stmt);
を
WmiResult access(String select_stmt, bool with_valus = true);
に変更。
wmi.cppのaccessメソッドを
/* * WQLを実行し結果セットを取得する * param : 実行するWQL文(String) * * return : IEnumWbemClassObjectポインター */ WmiResult WmiCall::access(String select_stmt, bool with_valus) { WmiResult result; if (pSvc != NULL) { IEnumWbemClassObject *pObjects = NULL; /* * Queryの実行 * return : WBEM_S_NO_ERROR = 正常にQueryできた * その他 = エラー * 参照:http://msdn.microsoft.com/en-us/library/aa392107(VS.85).aspx */ hRes = pSvc->ExecQuery(WQL, bstr_t(select_stmt.c_str()), WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_ENSURE_LOCATABLE, NULL, &pObjects); if (hRes != WBEM_S_NO_ERROR) { pObjects = NULL; errPos = 5; } if ((hRes = result.loadProperties(pObjects)) == WBEM_S_NO_ERROR) { if (with_valus) { if ((hRes = result.loadValues(pObjects)) != WBEM_S_NO_ERROR) { errPos = 7; } } } else { errPos = 7; } } else { errPos = 6; hRes = WBEM_E_FAILED; } return result; }
に変更しました。
そしてwmi.hファイルに新たなWmiResultクラスを定義
typedef vector<String> string_vector; typedef map<String, size_t> property_set; typedef property_set::iterator psIter; typedef property_set::const_iterator pscIter; typedef map<size_t, VARIANT> result_row; typedef result_row::iterator rrIter; typedef result_row::const_iterator rrcIter; typedef map<size_t, result_row> result_set; typedef result_set::iterator rsIter; typedef result_set::const_iterator rscIter; class WmiResult { public: WmiResult(); WmiResult(const WmiResult& from); ~WmiResult(); HRESULT loadProperties(IEnumWbemClassObject *pObjects); HRESULT loadValues(IEnumWbemClassObject *pObjects); size_t items(); size_t size(); string_vector getProperties(); String getProperty(size_t pos); result_set getResult(); private: size_t rows; size_t cols; property_set properties; result_set results; };
wmi.cppにWmiResultの本体を追加
// Constructor WmiResult::WmiResult() { cols = 0; rows = 0; } // Copy Constructor WmiResult::WmiResult(const WmiResult& from) { cols = from.cols; rows = from.rows; for (pscIter keys = from.properties.begin(); keys != from.properties.end(); keys++) { properties[keys->first] = keys->second; } VARIANT to_value; for (rscIter rs = from.results.begin(); rs != from.results.end(); rs++) { result_row to_row = result_row(); for (rrcIter rr = rs->second.begin(); rr != rs->second.end(); rr++) { VariantInit(&to_value); VariantCopy(&to_value, (VARIANT*)&rr->second); to_row[rr->first] = to_value; } results[rs->first] = to_row; } } // Destructor WmiResult::~WmiResult() { } /* * WMI呼び出しで戻ってきた結果セットからプロパティを保存する * param : 結果セット(IEnumWbemClassObjectポインター) * * return : HRESULT */ HRESULT WmiResult::loadProperties(IEnumWbemClassObject *pObjects) { HRESULT hRes; if (pObjects == NULL) { return WBEM_E_FAILED; } if ((hRes = pObjects->Reset()) == WBEM_S_NO_ERROR) { wchar_t **names = NULL; long lb = 0, ub = 0; ULONG uReturn = 0; IWbemClassObject *pclsObj[1]; if ((hRes = pObjects->Next(WBEM_INFINITE, 1, pclsObj, &uReturn)) == WBEM_S_NO_ERROR) { SAFEARRAY *pstrNames = NULL; if ((hRes = pclsObj[0]->GetNames(NULL, WBEM_FLAG_ALWAYS, NULL, &pstrNames)) == WBEM_S_NO_ERROR) { SafeArrayGetLBound(pstrNames, 1, &lb); SafeArrayGetUBound(pstrNames, 1, &ub); SafeArrayAccessData(pstrNames, (void **)&names); for (int i = lb; i <= ub; i++) { String name = String((_TCHAR *)bstr_t(names[i])); properties[name] = cols++; } SafeArrayUnaccessData(pstrNames); SafeArrayDestroy(pstrNames); } } } return hRes; } /* * WMI呼び出しで戻ってきた結果セットからデータを保存する * param : 結果セット(IEnumWbemClassObjectポインター) * * return : HRESULT */ HRESULT WmiResult::loadValues(IEnumWbemClassObject *pObjects) { HRESULT hRes; if (pObjects == NULL) { return WBEM_E_FAILED; } if ((hRes = pObjects->Reset()) == WBEM_S_NO_ERROR) { VARIANT vtProp, value; VariantInit(&vtProp); ULONG uReturn = 0; IWbemClassObject *pclsObj[1]; while (pObjects != NULL) { if(pObjects->Next(WBEM_INFINITE, 1, pclsObj, &uReturn) == WBEM_S_NO_ERROR) { result_row one_row = result_row(); for (psIter ps = properties.begin(); ps != properties.end(); ps++) { size_t col_pos = ps->second; _bstr_t key = bstr_t(ps->first.c_str()); hRes = pclsObj[0]->Get(key, 0, &vtProp, 0, 0); VariantInit(&value); if (vtProp.vt != 1) { VariantCopy(&value, &vtProp); } one_row[col_pos] = value; VariantClear(&vtProp); } results[rows++] = one_row; pclsObj[0]->Release(); } else break; } } return hRes; } /* * 結果セットの項目数を取得する * param : 無し * * return : size_t */ size_t WmiResult::items() { return properties.size(); } /* * 結果セットの行数を取得する * param : 無し * * return : size_t */ size_t WmiResult::size() { return results.size(); } /* * 結果セットのプロパティ一覧を取得する * param : 無し * * return : string_vector */ string_vector WmiResult::getProperties() { string_vector key_list; for (psIter item = properties.begin(); item != properties.end(); item++) { key_list.push_back(item->first); } return key_list; } /* * 結果セットのプロパティを取得する * param : 項目位置 * * return : String */ String WmiResult::getProperty(size_t pos) { string_vector key_list; for (psIter item = properties.begin(); item != properties.end(); item++) { if (item->second == pos) return item->first; } return _T(""); } /* * 結果セットを取得する * param : 無し * * return : result_set */ result_set WmiResult::getResult() { return results; }
もう少しクラスらしくは明日以降頑張ろうかな・・・。