È possibile richiamare COM da C. La sintassi è un po 'meno accogliente di quella di C++, ma funziona. COM è stato inizialmente progettato per funzionare da C o C++ e il supporto del linguaggio C nativo è incluso nei file di intestazione COM e WMI. Sarà lungo però ... il tuo programma sarà responsabile per l'assegnazione di tutti gli oggetti necessari, il controllo delle condizioni di errore da ogni chiamata COM e per il rilascio degli oggetti che ha istanziato.
Quando si utilizza la documentazione scritta in C++ in mente, convertire le chiamate COM della forma:
pSomething->Method(arg1, ...); // C++
a:
pSomething->lpVtbl->Method(pSomething, arg1, ...); // C
Di seguito si riporta il pezzo più breve di codice C ho potuto ottenere in realtà tirare alcune informazioni da WMI. Se ha successo, dovrebbe elencare i processori sul tuo computer, insieme alla loro frequenza di clock in MHz. Il programma si occupa di smaltire le risorse allocate, ma non esegue alcun controllo di errore (è necessario esaminare i valori di hr prima di continuare ogni passaggio).
Questa è un'applicazione di Visual Studio 2008 "Applicazione console Win32" con il file principale rinominato in estensione .c e i file extra stdafx rimossi. Per ottenere il collegamento al programma, assicurarsi di includere wbemuuid.lib nelle proprietà del progetto, in Proprietà di configurazione/Linker/Input/Dipendenze aggiuntive. Ha funzionato con successo sul mio box Vista.
#define _WIN32_WINNT 0x0400
#define _WIN32_DCOM
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <wbemidl.h>
void _tmain(int argc, _TCHAR* argv[])
{
// result code from COM calls
HRESULT hr = 0;
// COM interface pointers
IWbemLocator *locator = NULL;
IWbemServices *services = NULL;
IEnumWbemClassObject *results = NULL;
// BSTR strings we'll use (http://msdn.microsoft.com/en-us/library/ms221069.aspx)
BSTR resource = SysAllocString(L"ROOT\\CIMV2");
BSTR language = SysAllocString(L"WQL");
BSTR query = SysAllocString(L"SELECT * FROM Win32_Processor");
// initialize COM
hr = CoInitializeEx(0, COINIT_MULTITHREADED);
hr = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
// connect to WMI
hr = CoCreateInstance(&CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, &IID_IWbemLocator, (LPVOID *) &locator);
hr = locator->lpVtbl->ConnectServer(locator, resource, NULL, NULL, NULL, 0, NULL, NULL, &services);
// issue a WMI query
hr = services->lpVtbl->ExecQuery(services, language, query, WBEM_FLAG_BIDIRECTIONAL, NULL, &results);
// list the query results
if (results != NULL) {
IWbemClassObject *result = NULL;
ULONG returnedCount = 0;
// enumerate the retrieved objects
while((hr = results->lpVtbl->Next(results, WBEM_INFINITE, 1, &result, &returnedCount)) == S_OK) {
VARIANT name;
VARIANT speed;
// obtain the desired properties of the next result and print them out
hr = result->lpVtbl->Get(result, L"Name", 0, &name, 0, 0);
hr = result->lpVtbl->Get(result, L"MaxClockSpeed", 0, &speed, 0, 0);
wprintf(L"%s, %dMHz\r\n", name.bstrVal, speed.intVal);
// release the current result object
result->lpVtbl->Release(result);
}
}
// release WMI COM interfaces
results->lpVtbl->Release(results);
services->lpVtbl->Release(services);
locator->lpVtbl->Release(locator);
// unwind everything else we've allocated
CoUninitialize();
SysFreeString(query);
SysFreeString(language);
SysFreeString(resource);
}
Hi Oren, Grazie una tonnellata, che ha funzionato come un campione su Win2008 .Tuttavia, mi sono imbattuto in problemi di compilazione Quando ho provato su Visual Studio 2005, mettendoli qui di seguito: Errore C2065: 'COINIT_MULTITHREADED': identificatore non dichiarato errore C2065: 'EOAC_NONE': identificatore non dichiarato Qualche idea su come risolverli per il 2005? Grazie Som – smam
Prova ad aggiungere #define _WIN32_WINNT 0x0400 e #define _WIN32_DCOM prima dei file di inclusione. Se questo non risolve il problema, sostituisci entrambe le costanti mancanti con 0. –
Ciao Oren, Sì, ha funzionato con la prima libbra, si definisce ancora una volta grazie mille Som – smam