使用C ++ Builder XE4,我试图阅读Win32_DiskDrive信息,但我没有成功。
UnicodeString s;
Variant vX, vY, vZ, vi;
vX = Variant::CreateObject(L"WbemScripting.SWbemLocator");
vY = vX.OleFunction(L"ConnectServer");
vZ = vY.OleFunction(L"ExecQuery", L"SELECT * FROM Win32_DiskDrive");
int n = vZ.OlePropertyGet(L"Count"); // Error
s.SetLength(0);
for (int i = 0; i < n; i++) {
vi = vZ.OleFunction<int>(L"ItemIndex", i);
s = vi.OlePropertyGet(L"Caption");
RichEdit1->Lines->Add(s);
}
我在
收到错误消息“无效查询” int n = vZ.OlePropertyGet(L"Count"); // Error
当我检查vZ时,IDE会显示“{{}}”。这是否意味着我在获取vZ或之前的某个地方时犯了错误?
我的环境是Windows7 Professional。
对上述代码进行任何更正都会有所帮助。
答案 0 :(得分:4)
从C ++访问WMI的最常用方法是直接使用WMI COM客户端(wbemcli.h)。
试试这个样本。
#pragma hdrstop
#include <iostream>
using namespace std;
#include <wbemcli.h>
#include <comdef.h>
#pragma argsused
int main(int argc, char* argv[])
{
BSTR strNetworkResource;
strNetworkResource = L"\\\\.\\root\\CIMV2";
// Initialize COM. ------------------------------------------
HRESULT hres;
hres = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hres))
{
cout << "Failed to initialize COM library. Error code = 0x" << hex << hres << endl;
cout << _com_error(hres).ErrorMessage() << endl;
cout << "press enter to exit" << endl;
cin.get();
return 1; // Program has failed.
}
// Set general COM security levels --------------------------
hres = CoInitializeSecurity(
NULL,
-1, // COM authentication
NULL, // Authentication services
NULL, // Reserved
RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication
RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation
NULL, // Authentication info
EOAC_NONE, // Additional capabilities
NULL // Reserved
);
if (FAILED(hres))
{
cout << "Failed to initialize security. Error code = 0x" << hex << hres << endl;
cout << _com_error(hres).ErrorMessage() << endl;
CoUninitialize();
cout << "press enter to exit" << endl;
cin.get();
return 1; // Program has failed.
}
// 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." << " Err code = 0x" << hex << hres << endl;
cout << _com_error(hres).ErrorMessage() << endl;
CoUninitialize();
cout << "press enter to exit" << endl;
cin.get();
return 1; // Program has failed.
}
// Connect to WMI through the IWbemLocator::ConnectServer method
IWbemServices *pSvc = NULL;
hres = pLoc->ConnectServer(
strNetworkResource, // Object path of WMI namespace
NULL, // User name. NULL = current user
NULL, // User password. NULL = current
0, // Locale. NULL indicates current
NULL, // Security flags.
0, // Authority (e.g. Kerberos)
0, // Context object
&pSvc // pointer to IWbemServices proxy
);
if (FAILED(hres))
{
cout << "Could not connect. Error code = 0x" << hex << hres << endl;
cout << _com_error(hres).ErrorMessage() << endl;
pLoc->Release();
CoUninitialize();
cout << "press enter to exit" << endl;
cin.get();
return 1; // Program has failed.
}
cout << "Connected to root\\CIMV2 WMI namespace" << endl;
// Set security levels on the proxy -------------------------
hres = CoSetProxyBlanket(
pSvc, // Indicates the proxy to set
RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx
RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx
NULL, // Server principal name
RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx
RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
NULL, // client identity
EOAC_NONE // proxy capabilities
);
if (FAILED(hres))
{
cout << "Could not set proxy blanket. Error code = 0x" << hex << hres << endl;
cout << _com_error(hres).ErrorMessage() << endl;
pSvc->Release();
pLoc->Release();
CoUninitialize();
cout << "press enter to exit" << endl;
cin.get();
return 1; // Program has failed.
}
// Use the IWbemServices pointer to make requests of WMI ----
IEnumWbemClassObject* pEnumerator = NULL;
hres = pSvc->ExecQuery( L"WQL", L"SELECT * FROM Win32_DiskDrive",
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);
if (FAILED(hres))
{
cout << "ExecQuery failed" << " Error code = 0x" << hex << hres << endl;
cout << _com_error(hres).ErrorMessage() << endl;
pSvc->Release();
pLoc->Release();
CoUninitialize();
cout << "press enter to exit" << endl;
cin.get();
return 1; // Program has failed.
}
// Get the data from the WQL sentence
IWbemClassObject *pclsObj = NULL;
ULONG uReturn = 0;
while (pEnumerator)
{
HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
if(0 == uReturn || FAILED(hr))
break;
VARIANT vtProp;
hr = pclsObj->Get(L"Caption", 0, &vtProp, 0, 0);// String
if (!FAILED(hr))
{
if ((vtProp.vt==VT_NULL) || (vtProp.vt==VT_EMPTY))
wcout << "Caption : " << ((vtProp.vt==VT_NULL) ? "NULL" : "EMPTY") << endl;
else
if ((vtProp.vt & VT_ARRAY))
wcout << "Caption : " << "Array types not supported (yet)" << endl;
else
wcout << "Caption : " << vtProp.bstrVal << endl;
}
VariantClear(&vtProp);
hr = pclsObj->Get(L"DeviceID", 0, &vtProp, 0, 0);// String
if (!FAILED(hr))
{
if ((vtProp.vt==VT_NULL) || (vtProp.vt==VT_EMPTY))
wcout << "DeviceID : " << ((vtProp.vt==VT_NULL) ? "NULL" : "EMPTY") << endl;
else
if ((vtProp.vt & VT_ARRAY))
wcout << "DeviceID : " << "Array types not supported (yet)" << endl;
else
wcout << "DeviceID : " << vtProp.bstrVal << endl;
}
VariantClear(&vtProp);
pclsObj->Release();
pclsObj=NULL;
}
// Cleanup
pSvc->Release();
pLoc->Release();
pEnumerator->Release();
if (pclsObj!=NULL)
pclsObj->Release();
CoUninitialize();
cout << "press enter to exit" << endl;
cin.get();
return 0; // Program successfully completed.
}
注意:如果您不熟悉从C ++与WMI交互,可以使用WMI Delphi Code Creator来帮助您浏览WMI属性并创建C ++代码以访问WMI。
答案 1 :(得分:1)
我想,如果您使代码看起来更加用户友好,那将会有所帮助:
UnicodeString s;
Variant vX, vY, vZ, vi;
vX = Variant::CreateObject(L"WbemScripting.SWbemLocator");
vY = vX.OleFunction(L"ConnectServer");
vZ = vY.OleFunction(L"ExecQuery", L"SELECT * FROM Win32_DiskDrive");
int n = vZ.OlePropertyGet(L"Count"); // Error
s.SetLength(0);
for (int i = 0; i < n; i++) {
vi = vZ.OleFunction<int>(L"ItemIndex", i);
s = vi.OlePropertyGet(L"Caption");
RichEdit1->Lines->Add(s);
}
尝试一下:
RichEdit1->Lines->Clear();
Variant l = Variant::CreateObject("WbemScripting.SWbemLocator");
Variant svc = l.OleFunction("ConnectServer");
Variant objs = svc.OleFunction("ExecQuery", OleVariant("SELECT * FROM Win32_DiskDrive"));
Variant n = objs.OlePropertyGet("Count"); // Error
for (int i = 0; i < n; i++)
{
Variant obj = objs.OleFunction<int>("ItemIndex", OleVariant(i));
Variant props = obj.OlePropertyGet("Properties_");
Variant prop = props.OleFunction("Item", OleVariant("Caption"));
String Value = prop.OlePropertyGet("Value");
RichEdit1->Lines->Add(Value);
}