Można powołać COM z C. Składnia jest nieco mniej przyjazny niż C++, ale to działa. COM został pierwotnie zaprojektowany do pracy z C lub C++, a natywna obsługa języka C jest zawarta w plikach nagłówkowych COM i WMI. Będzie jednak długo ... Twój program będzie odpowiedzialny za przydzielenie wszystkich potrzebnych obiektów, sprawdzanie warunków błędów od każdego wywołania COM i uwolnienie obiektów, które zostały utworzone.
Podczas korzystania dokumentację pisemną z C++ na uwadze, konwersja połączenia COM w postaci:
pSomething->Method(arg1, ...); // C++
do:
pSomething->lpVtbl->Method(pSomething, arg1, ...); // C
Poniżej jest najkrótszy kawałek kodu C mogłem dostać się do faktycznie ciągnąć niektóre informacje z WMI. Jeśli się powiedzie, powinien wymienić procesory na komputerze wraz z częstotliwością taktowania w MHz. Program zajmuje się wyrzucaniem przydzielonych zasobów, ale nie sprawdza żadnych błędów (powinieneś spojrzeć na te wartości hr przed kontynuowaniem każdego kroku).
To jest wizualne studio 2008 "Win32 Console Application" z głównym plikiem zmienionym na rozszerzenie .c, a dodatkowe pliki stdafx usunięte. Aby uzyskać dostęp do programu, upewnij się, że wbemuuid.lib zawiera właściwości projektu, w obszarze Właściwości konfiguracji/Linker/Wejście/Dodatkowe zależności. Uruchomił się pomyślnie na moim pudełku 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, Dzięki ton, który pracował jak mistrz na Win2008 .Jednak wpadłem na kwestie kompilacji kiedy pierwszy raz spróbowałem w Visual Studio 2005, umieszczając je poniżej: error C2065: „COINIT_MULTITHREADED”: niezadeklarowany identyfikator błąd C2065: "EOAC_NONE": niezadeklarowany identyfikator Czy masz pomysł, jak je rozwiązać na rok 2005? Dzięki Som – smam
Spróbuj dodać #define _WIN32_WINNT 0x0400 i #define _WIN32_DCOM przed dołączeniem plików. Jeśli to nie rozwiąże problemu, po prostu zastąp obie brakujące stałe wartością 0. –
Hi Oren, Tak, zadziałało to przy pierwszym zderzeniu, po raz kolejny bardzo dziękuję Som – smam