puede invocar COM de C. La sintaxis es un poco menos agradable que la de C++, pero funciona. COM se diseñó inicialmente para funcionar desde C o C++, y el soporte nativo de lenguaje C se incluye en los archivos de encabezado COM y WMI. Sin embargo, será largo ... su programa será responsable de asignar todos los objetos necesarios, verificar las condiciones de error de todas y cada una de las llamadas COM y liberar los objetos que creó.
Al utilizar la documentación escrita con C++ en mente, convertir llamadas COM de la forma:
pSomething->Method(arg1, ...); // C++
a:
pSomething->lpVtbl->Method(pSomething, arg1, ...); // C
A continuación se muestra la pieza más corta del código C que pudiera llegar a realidad tirar algo de información de WMI. Si tiene éxito, debe enumerar los procesadores en su computadora, junto con su frecuencia de reloj en MHz. El programa se encarga de eliminar los recursos que asigna, pero no realiza ningún tipo de comprobación de errores (debe mirar esos valores hr antes de continuar con cada paso).
Esto es un estudio visual 2008 "Aplicación de consola Win32" con el archivo principal renombrado a una extensión .c, y los archivos extra stdafx eliminados. Para que el programa se vincule, asegúrese de incluir wbemuuid.lib en las propiedades del proyecto, en Propiedades de configuración/Enlazador/Entrada/Dependencias adicionales. Funcionó con éxito en mi caja de 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);
}
Hola Oren, Gracias por tonelada, que funcionó como un campeón en Win2008 .Sin embargo, me encontré con problemas de compilación La primera vez que probé en Visual Studio 2005, poniéndolos a continuación: error C2065: 'COINIT_MULTITHREADED': identificador no declarado error C2065: 'EOAC_NONE': identificador no declarado ¿Alguna idea sobre cómo resolverlos para 2005? Gracias Som – smam
Pruebe agregar #define _WIN32_WINNT 0x0400 y #define _WIN32_DCOM antes de incluir archivos. Si eso no resuelve el problema, simplemente reemplace las dos constantes que faltan por 0. –
Hola Oren, Sí, funcionó con la primera libra se define a sí misma, una vez más muchas gracias Som – smam