WindowsのAPIを使ったサンプルプログラム(エラー処理を含む)です。

void __fastcall TForm1::Button3Click(TObject *Sender)
{
// Windows の API

HRESULT hr;
VARIANT var;
VARIANT varResult;
DISPPARAMS dispParams;

CoInitialize(NULL);

CLSID clsid;
hr = CLSIDFromProgID(L"WbemScripting.SWbemLocator", &clsid);
if (FAILED(hr)) {
CoUninitialize();
RichEdit1->Lines->Add(ResultString(hr));
return;
}

IDispatch *pLocator;
hr = CoCreateInstance(
clsid, // REFCLSID rclsid
NULL, // LPUNKNOWN pUnkOuter
CLSCTX_INPROC_SERVER, // DWORD dwClsContext
// CLSCTX_LOCAL_SERVER,
// CLSCTX_REMOTE_SERVER,
// IID_PPV_ARGS(&pLocator) ==>> エラーになる
__uuidof(IDispatch), // __uuidof(変数名) はエラー
(void **)&pLocator
);
if (FAILED(hr)) {
CoUninitialize();
RichEdit1->Lines->Add(ResultString(hr));
return;
}

// vY = vX.OleFunction("ConnectServer");
DISPID dispid;
OLECHAR *pNames[1];
pNames[0] = L"ConnectServer";
hr = pLocator->GetIDsOfNames(
IID_NULL, // REFIID riid ([in]Reserved)
pNames, // OLECHAR FAR* FAR* rgszNames,
1,
LOCALE_USER_DEFAULT,
&dispid
);
if (FAILED(hr)) {
pLocator->Release();
CoUninitialize();
RichEdit1->Lines->Add(ResultString(hr));
return;
}

dispParams.cArgs = 0;
dispParams.rgvarg = NULL;
dispParams.cNamedArgs = 0;
dispParams.rgdispidNamedArgs = NULL;
VariantInit(&varResult);
hr = pLocator->Invoke(
dispid, // dispatch ID
IID_NULL, // Reserved
LOCALE_SYSTEM_DEFAULT, // locale context
DISPATCH_METHOD, // _PROPERTYGET, _PROPERTYPUT, _PROPERTYREF
&dispParams, // pDispParams
&varResult, // result
NULL, // exception information
NULL // puArgErr
);
if (FAILED(hr)) {
pLocator->Release();
CoUninitialize();
RichEdit1->Lines->Add(ResultString(hr));
return;
}
IDispatch *pServer = varResult.pdispVal;
// VariantClear(&varResult) をコールすると次の pServer->GetIdsOfNames() がエラーになる
// VariantClear() 内で pServer->Release() がコールされているのか?


// vZ = vY.OleFunction("ExecQuery", "SELECT * FROM Win32_DiskDrive");
pNames[0] = L"ExecQuery";
hr = pServer->GetIDsOfNames(
IID_NULL, // REFIID riid ([in]Reserved)
pNames, // OLECHAR FAR* FAR* rgszNames,
1,
LOCALE_USER_DEFAULT,
&dispid
);
if (FAILED(hr)) {
pServer->Release();
pLocator->Release();
CoUninitialize();
RichEdit1->Lines->Add(ResultString(hr));
return;
}

var.vt = VT_BSTR;
var.bstrVal = SysAllocString(L"SELECT * FROM Win32_DiskDrive");
dispParams.cArgs = 1;
dispParams.rgvarg = &var;
dispParams.cNamedArgs = 0;
dispParams.rgdispidNamedArgs = NULL;
VariantInit(&varResult);
hr = pServer->Invoke(
dispid, // dispatch ID
IID_NULL, // Reserved
LOCALE_SYSTEM_DEFAULT, // locale context
DISPATCH_METHOD, // _PROPERTYGET, _PROPERTYPUT, _PROPERTYREF
&dispParams, // pDispParams
&varResult, // result
NULL, // exception information
NULL // puArgErr
);
SysFreeString(var.bstrVal);
if (FAILED(hr)) {
pServer->Release();
pLocator->Release();
CoUninitialize();
RichEdit1->Lines->Add(ResultString(hr));
return;
}
IDispatch *pItems = varResult.pdispVal;
//VariantClear(&varResult);

pNames[0] = L"Count";
hr = pItems->GetIDsOfNames(
IID_NULL, // REFIID riid ([in]Reserved)
pNames, // OLECHAR FAR* FAR* rgszNames,
1,
LOCALE_USER_DEFAULT,
&dispid
);
if (FAILED(hr)) {
pItems->Release();
pServer->Release();
pLocator->Release();
CoUninitialize();
RichEdit1->Lines->Add(ResultString(hr));
return;
}
dispParams.cArgs = 0;
dispParams.rgvarg = NULL;
dispParams.cNamedArgs = 0;
dispParams.rgdispidNamedArgs = NULL;
VariantInit(&varResult);
hr = pItems->Invoke(
dispid, // dispatch ID
IID_NULL, // Reserved
LOCALE_SYSTEM_DEFAULT, // locale context
DISPATCH_PROPERTYGET, // _PROPERTYGET, _PROPERTYPUT, _PROPERTYREF
&dispParams, // pDispParams
&varResult, // result
NULL, // exception information
NULL // puArgErr
);
if (FAILED(hr)) {
pItems->Release();
pServer->Release();
pLocator->Release();
CoUninitialize();
RichEdit1->Lines->Add(ResultString(hr));
return;
}
long count = varResult.lVal;
VariantClear(&varResult);


pNames[0] = L"ItemIndex";
hr = pItems->GetIDsOfNames(
IID_NULL, // REFIID riid ([in]Reserved)
pNames, // OLECHAR FAR* FAR* rgszNames,
1,
LOCALE_USER_DEFAULT,
&dispid
);
if (FAILED(hr)) {
pItems->Release();
pServer->Release();
pLocator->Release();
CoUninitialize();
RichEdit1->Lines->Add(ResultString(hr));
return;
}
for (long i = 0; i < count; i++) {
var.vt = VT_I4;
var.lVal = i;
dispParams.cArgs = 1;
dispParams.rgvarg = &var;
dispParams.cNamedArgs = 0;
dispParams.rgdispidNamedArgs = NULL;
VariantInit(&varResult);
hr = pItems->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
DISPATCH_METHOD, &dispParams, &varResult, NULL, NULL);
if (FAILED(hr)) {
RichEdit1->Lines->Add(ResultString(hr));
continue;
}
IDispatch *pOne = varResult.pdispVal;
//VariantClear(&varResult);

DISPID diCaption;
pNames[0] = L"Caption";
hr = pOne->GetIDsOfNames(IID_NULL,
pNames, 1, LOCALE_USER_DEFAULT, &diCaption);
if (FAILED(hr)) {
pOne->Release();
RichEdit1->Lines->Add(ResultString(hr));
continue;
}
dispParams.cArgs = 0;
dispParams.rgvarg = NULL;
dispParams.cNamedArgs = 0;
dispParams.rgdispidNamedArgs = NULL;
VariantInit(&varResult);
hr = pOne->Invoke(diCaption, IID_NULL, LOCALE_SYSTEM_DEFAULT,
DISPATCH_PROPERTYGET, &dispParams, &varResult, NULL, NULL);
if (SUCCEEDED(hr)) {
if (varResult.vt == VT_BSTR) {
RichEdit1->Lines->Add(AnsiString(varResult.bstrVal));
}
} else {
RichEdit1->Lines->Add(ResultString(hr));
}
VariantClear(&varResult);

pOne->Release();
}

pItems->Release();
pServer->Release();
pLocator->Release();
CoUninitialize();
}