Windows Management Instrumentation (4-3)
以下のような処理に変更後テストをするとエラーが発生。
void Win32_OperatingSystem() { WmiResult resulta = wmi.access(_T("SELECT * FROM Win32_OperatingSystem")); if (resulta.items() == 0) { String msg = wmi.getErrorMessage(); return; } COUT << resulta.print(); String systemDrive = resulta.getString(_T("SystemDrive")); String wql = WmiCall::createSelect(_T("ASSOCIATORS OF {Win32_LogicalDisk.DeviceID=\"%s\"} WHERE AssocClass = Win32_LogicalDiskToPartition ResultClass = Win32_DiskPartition"), systemDrive.c_str(), NULL); resulta = wmi.access(wql); if (resulta.items() == 0) { String msg = wmi.getErrorMessage(); return; } COUT << resulta.print(); }
デバッグしてみると、
resulta = wmi.access(wql);
でデータをコピーした後にデストラクタが起動している感じ・・・、"operator="を定義していなかったのが原因でした。
そこで、wmi.hに
void copy(const WmiResult& from); WmiResult& operator=(const WmiResult& from);
を追加し、
wmi.cpp中のロジックを
/* * WmiResultクラスをコピーする */ void WmiResult::copy(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++) { /* * VARIANTデータエリアの初期化(初期化しておかないとVariantCopyの時にエリアを開放しようとしてエラーになる) * return : 無し * 参照:http://msdn.microsoft.com/en-us/library/ms221402.aspx */ VariantInit(&to_value); /* * VARIANTのデータをコピー * return : S_OK = 正常にコピーできた(ここでは結果はチェックしない) * その他 = エラー * 参照:http://msdn.microsoft.com/en-us/library/ms221697.aspx */ VariantCopy(&to_value, (VARIANT*)&rr->second); to_row[rr->first] = to_value; } results[rs->first] = to_row; } } /* * デフォルトのCopy Constructorでは、VARIANTのSAFEARRAYタイプのデータを * 正しくコピー出来ない為に作成 */ WmiResult::WmiResult(const WmiResult& from) { copy(from); } /* * "=(代入)"オペレータの処理 */ WmiResult& WmiResult::operator=(const WmiResult& from) { copy(from); return *this; }
に修正しました。