Wmi mit C++ benutzen ?



  • Hallo,
    normalerweise programmiere ich nicht mit C++, aber leider brache ich jetzt direkten zugriff auf einige Windows daten.

    Ich brache zugriff auf einige WMI daten, zb:
    das bios:
    http://msdn.microsoft.com/en-us/library/aa394077(VS.85).aspx

    Leider scheitere ich daran ein sinnvolles (funktionierendes) Beispiel zu finden, das nicht in VB Script ist 😞

    Ich hoffe jemand hier kann mir dabei helfen?

    ps. ich hoffe das ist im richtigen Board, war mir nicht sicher.



  • Bitte sehr:

    #include <windows.h>
    #include <wbemdisp.h>
    #include <tchar.h>
    #pragma comment(lib, "wbemuuid.lib")
    #pragma comment(lib, "oleaut32.lib")
    
    HRESULT GetPropertyString(ISWbemPropertySet *properties, LPWSTR name, BSTR *ppv)
    {
    	ISWbemProperty *property;
    	*ppv = 0;
    	HRESULT hr;
    	if (SUCCEEDED(hr=properties->Item(name, 0, &property)))
    	{
    		// #define VT_BSTR_ARRAY VT_BSTR|VT_ARRAY
    		#define VT_VARIANT_ARRAY (VT_VARIANT|VT_ARRAY) // EDIT
    
    		VARIANT vProp;
    		vProp.vt = VT_EMPTY; // required
    
    		if (SUCCEEDED(hr=property->get_Value(&vProp)))
    		{
    			if (vProp.vt==VT_BSTR && vProp.bstrVal)
    			{
    				*ppv = vProp.bstrVal;
    				vProp.vt = VT_EMPTY; // disable VariantClear
    			}
    			else if (SUCCEEDED(hr=VariantChangeType(&vProp, &vProp, 0, VT_BSTR)) && vProp.bstrVal)
    			{
    				*ppv = vProp.bstrVal;
    				vProp.vt = VT_EMPTY;
    			}
    			else if (vProp.vt==VT_BSTR && !vProp.bstrVal)
    			{
    				*ppv = SysAllocString(L"<L E E R>");
    				vProp.vt = VT_EMPTY;
    			}
    			else if ((vProp.vt==VT_VARIANT_ARRAY) && vProp.parray && ((int)SafeArrayGetDim(vProp.parray)==1)) // EDIT
    			{
    				// handle array of strings/numbers: string\nstring\n ... string\n
    				WCHAR *append;
    				VARIANT v;
    				long a, cch=0;
    				long count = vProp.parray->rgsabound[0].cElements;
    
    				for (a=0; a<count; a++)
    				{
    					if (!SafeArrayGetElement(vProp.parray, &a, &v))
    					{
    						//cch += (SysStringLen(v.bstrVal)+2);
    						if (!VariantChangeType(&v, &v, 0, VT_BSTR)) // EDIT
    						{
    							cch += (SysStringLen(v.bstrVal)+2);
    						}
    						VariantClear(&v);
    					}
    				}
    				*ppv = append = SysAllocStringLen(NULL, cch+1);
    
    				if (!append)
    				{
    					hr = E_OUTOFMEMORY;
    				}
    				else
    				{
    					hr = S_OK;
    					for (a=0; a<count; a++)
    					{
    						if (!SafeArrayGetElement(vProp.parray, (LONG*)&a, &v))
    						{
    							//append = &append[swprintf(append, L"%s\r\n", v.bstrVal)]; // EDIT
    							if (!VariantChangeType(&v, &v, 0, VT_BSTR))
    							{
    								append = &append[swprintf(append, L"%s\r\n", v.bstrVal)];
    							}
    							VariantClear(&v);
    						}
    					}
    				}
    			}
    			else
    			{
    				hr = E_FAIL;
    			}
    			VariantClear(&vProp);
    		}
    		property->Release();
    	}
    	return hr;
    }
    
    void ShowError(HRESULT hr, LPTSTR info) // EDIT
    {
    	TCHAR text[300];
    	int cch = _sntprintf(text, 300, TEXT("%s failed with error 0x%.8X\n"), info, hr);
    	FormatMessage(0x000010FF, 0, hr, 0, &text[cch], 300-cch, 0);
    	MessageBox(0, text, 0, MB_ICONHAND);
    }
    
    extern"C" int main()
    {
    	CoInitialize(0);
    	ISWbemServices *services = 0;
    	ISWbemObjectSet *set = 0;
    	IUnknown *unk = 0;
    	IEnumVARIANT *enumv = 0;
    	VARIANT v;
    	HRESULT hr;
    
    	#define EXIT_DO(x,y) {x=0; ShowError(hr,y);break;}
    	do
    	{
    		if (FAILED(hr=CoGetObject(L"winmgmts:{impersonationLevel=impersonate}!\\\\.\\root\\cimv2",
    				NULL, IID_ISWbemServices, (void**)&services)))
    			EXIT_DO(services, TEXT("CoGetObject"));
    
    		if (FAILED(hr=services->ExecQuery(L"Select * from Win32_BIOS", L"WQL", 0, NULL, &set)))
    			EXIT_DO(set, TEXT("ExecQuery"));
    
    		if (FAILED(hr=set->get__NewEnum(&unk)))
    			EXIT_DO(unk, TEXT("get__NewEnum"));
    
    		if (FAILED(hr=unk->QueryInterface(IID_IEnumVARIANT, (void**)&enumv)))
    			EXIT_DO(enumv, TEXT("IEnumVARIANT"));
    
    		// now use IF or WHILE
    		if (!enumv->Next(1, &v, NULL))
    		{
    			if (!VariantChangeType(&v, &v, 0, VT_UNKNOWN))
    			{
    				ISWbemObject *object;
    				if (!v.punkVal->QueryInterface(IID_ISWbemObject, (void**)&object))
    				{
    					ISWbemPropertySet *properties;
    					if (!object->get_Properties_(&properties))
    					{
    						BSTR bstrText;
    						if (FAILED(hr=GetPropertyString(properties, L"BIOSVersion", &bstrText)))
    						{
    							ShowError(hr, TEXT("GetPropertyString"));
    						}
    						else
    						{
    							MessageBox(0, bstrText, L"Bios Version", 0);
    							SysFreeString(bstrText);
    						}
    						properties->Release();
    					}
    					object->Release();
    				}
    			}
    			VariantClear(&v);
    		}
    
    	} while (0);
    
    	#define Release(x) if (x) x->Release();
    	Release(enumv);
    	Release(unk);
    	Release(set);
    	Release(services);
    	CoUninitialize();
    	return 0;
    }
    


  • Super 🙂
    das funktioniert soweit,
    habe den code jetzt etwas an meine Vorlieben angepasst 😉

    Eine frage dazu noch: Gibt es einen Grund warum du alle Fehler Manuell abfragst statt ein try catch darumzukleben?
    Programmiere normalerweise mit Java, und habe gesehen das es das in c++ auch gibt.



  • Wo werden hier den Exceptions geworfen, die man abfangen könnte?



  • Naja dachte überall sozusagen,
    dachte die sind wie die in Java...
    Da hat man normalerweise bei fehlerfällen irgetwo was was ne Exception wirft.



  • Code updated, habe keine Ahnung warum "BIOSVersion" mit BSTR|ARRAY funtzte. Wahrscheinlich preprocessor bug mit x|y ohne ().

    Empire Phoenix, es gibt keinen Grund, das war nur ein Beispiel. Du kannst ShowError immer mit throw ersetzen.
    (Reale) Exceptions kann man abfragen nur von IDispatch::Invoke

    HRESULT Invoke( 
      DISPID  dispIdMember,      // z.B. services->GetIDsOfNames(array(L"ExecQuery")) =pseudocode
      REFIID  riid,              // IID_NULL
      LCID  lcid,                // LOCALE_NEUTRAL
      WORD  wFlags,              // DISPATCH_METHOD, DISPATCH_PROPERTYGET...
      DISPPARAMS*  pDispParams,  // arguments for ExecQuery method
      VARIANT*  pVarResult,      // optional
      EXCEPINFO*  pExcepInfo,    // opt. will be filled in if DISP_E_EXCEPTION is returned
      unsigned int*  puArgErr    // opt. returned when DISP_E_TYPEMISMATCH or DISP_E_PARAMNOTFOUND is returned
    );
    
    EXCEPINFO excep;
    if ((hr=object->Invoke(..., &excep, NULL)) == DISP_E_EXCEPTION)
    {
    	AfxThrowOleDispatchException(excep.wCode, excep.bstrDescription, excep.dwHelpContext);
    }
    else if (FAILED(hr))
    {
    	throw hr;
    }
    

    Beispiel: XLCLIENT: Automatisierungsclient für Excel
    AutoWrap() - Automation helper function



  • Habe jetzt alles soweit zum laufen gebracht,
    dank dir 🙂 👍


Anmelden zum Antworten