WMI: Array-Wert auslesen



  • Hi,

    hab noch ne Frage zu WMI: und zwar beim Auslesen von Array-Werten. Vom Prinzip her funktioniert es so, aber vielleicht gibt es eine einfachere Möglichkeit bzw. eine die nicht soviele Zeilen Code benötigt? 😋

    VARIANT *pVal = new VARIANT;
    			SAFEARRAY * pSA; 
    			SAFEARRAYBOUND rgsabound; 
    			rgsabound.lLbound = 0;
    			rgsabound.cElements = 1;
    			pSA = SafeArrayCreate(VT_BSTR, 1, &rgsabound);
    
    			V_ARRAY(pVal) = pSA;
    			BSTR *pStrs = 0;
    			SafeArrayAccessData(pSA, ( void **)&pStrs );
    
    			hr = pclsObj->Get(value2, 0, pVal, 0, 0);
    			pSA = pVal->parray;
    
    			long lstart; 
    			hr = SafeArrayGetLBound( pSA, 1, &lstart );
    			if(FAILED(hr))	return CString();
    
    			long lend; 
    			hr = SafeArrayGetUBound( pSA, 1, &lend );
    			if(FAILED(hr))	return CString();
    
    			BSTR value; 
    			for(int index=lstart; index <= lend; index++) 
    			{
    				long indices[]={index,0};
    				SafeArrayGetElement(pSA, indices, &value);
    			}
    
    			hr = SafeArrayUnaccessData(pSA);    
                if(FAILED(hr)) return CString();
    

    Gruß
    Jakob


  • Mod

    Warum führst Du nich teinfach gleich den Get aus? IMHO musst Du der Funktion doch keinen gefüllten Variant anbieten? Ist diese Get Funktion nicht sowieso nur als [out] definiert.

    Es fehlt eher noch Code:
    Du hast vergessen zu prüfen ob Du wirklich auch einen Array mit BSTR zurück bekomen hast. 🙂

    SafeArrays sind eine üble Sache. Da komt man nicht einfachdrum herum...



  • Martin Richter schrieb:

    Warum führst Du nich teinfach gleich den Get aus? IMHO musst Du der Funktion doch keinen gefüllten Variant anbieten? Ist diese Get Funktion nicht sowieso nur als [out] definiert.

    Wenn ich als Returnwert ein Array erwarte, kann ich doch den Get nicht sofort ausführen? Weil dann pVal VT_EMPTY als Wert liefern würde.

    Martin Richter schrieb:

    Es fehlt eher noch Code:
    Du hast vergessen zu prüfen ob Du wirklich auch einen Array mit BSTR zurück bekomen hast. 🙂

    Wie überprüfe ich das?

    Martin Richter schrieb:

    SafeArrays sind eine üble Sache. Da komt man nicht einfachdrum herum...

    Üble Sache im Sinne von - man sollte sie nicht einsetzen? Oder man kann es schlichtweg nicht vereinfachen?


  • Mod

    1. Ist Get nun eine [out]. Dann musst Du gar nichts für den VARIANT vorbereiten. Dein Code würde sogar ein Leak erzeugen.
    2. Du musst den Typ prüfen im Variant !!! vt! VT_ARRAY|VT_BSTR
    3. Warum machst Du ein new VARIANT? Warum benutzt Du nicht den Stack.
    4. Warum benutzt Du nicht die _varient_t oder CCOMVariant Klassen, die machen einige seinfacher.
    5. Der Umgag mit SafeArrays ist nicht zu vereinfachen. Er war schon immer nicht einfach.

    Mein Eindruck ist, dass Du mit COM und Automation total im Nebel herumstocherst. Ich rate Dir mal ein paar Basics zu lesen...



  • Martin Richter schrieb:

    1. Ist Get nun eine [out]. Dann musst Du gar nichts für den VARIANT vorbereiten. Dein Code würde sogar ein Leak erzeugen.
    2. Du musst den Typ prüfen im Variant !!! vt! VT_ARRAY|VT_BSTR
    3. Warum machst Du ein new VARIANT? Warum benutzt Du nicht den Stack.
    4. Warum benutzt Du nicht die _varient_t oder CCOMVariant Klassen, die machen einige seinfacher.
    5. Der Umgag mit SafeArrays ist nicht zu vereinfachen. Er war schon immer nicht einfach.

    Mein Eindruck ist, dass Du mit COM und Automation total im Nebel herumstocherst. Ich rate Dir mal ein paar Basics zu lesen...

    Ja bei diesen Themen stehe ich noch ganz am Anfang.

    Welchen Vorteil / Unterschied macht es _varient_t anstatt VARIANT zu verwenden?

    Und das mit dem Leak hab ich noch nicht verstanden (im obigen Code fehlt noch die letzte Zeile delete pVal;). Wo findet dieses Leak statt?

    if(pVal.vt ==(VT_ARRAY | VT_BSTR))
    {
       //hier alles initialisieren für Safearray etc.
    
    }
    else if(pVal.vt ==(VT_BSTR))
    {
        //lediglich wert aus Get auslesen
    }
    

    Gruß Jakob (und danke für deine Comments)



  • Bist du denn sicher, dass du _unbedingt_ ein SAFEARRAY brauchst. Ich habe mir einmal die MSDN dazu angeschaut, das sieht ja furchtbar aus 😮 .
    Zumindest, wenn du C++ programmierst, hast du doch viel elegantere Möglichkeiten, Speicher anzufordern (ist aus deinem bisher geposteten Code nicht ersichtlich).



  • Vicious Falcon schrieb:

    Bist du denn sicher, dass du _unbedingt_ ein SAFEARRAY brauchst. Ich habe mir einmal die MSDN dazu angeschaut, das sieht ja furchtbar aus 😮 .
    Zumindest, wenn du C++ programmierst, hast du doch viel elegantere Möglichkeiten, Speicher anzufordern (ist aus deinem bisher geposteten Code nicht ersichtlich).

    Hmm das weiß ich leider auch noch nicht so genau... Hab mir halt auch die Beispiele angeschaut in der MSDN etc. und die verwendeten stets so ein schönes SAFEARRAY

    Letzendlich möchte ich verschiedene Wert im Netzwerkbereich, wie die IP, Gateway etc. auslesen können und diese Werte liegen als ARRAY vor.

    if(pVal.vt ==(VT_ARRAY | VT_BSTR))
    

    Diese Annahme ist daher in diesen Fällen richtig. Aber ob es jetzt auch noch andere Möglichkeiten gibt mit malloc oder (ich arbeite eigentlich mit der MFC) mit CStrings - das weiß ich nicht und hab ich leider im Netz auch nicht sehen können (das meiste mit WMI ist ja VB.script).



  • Du kannst dir mal die Windows-Sockets anschauen. Vieles, was du haben möchtest, lässt sich auch so in Erfahrung bringen.
    Bspw. die IP_Adresse:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-39385.html



  • Vicious Falcon schrieb:

    Du kannst dir mal die Windows-Sockets anschauen. Vieles, was du haben möchtest, lässt sich auch so in Erfahrung bringen.
    Bspw. die IP_Adresse:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-39385.html

    Ich möchte die IP auch ändern können - genauso wie Subnet etc. Von daher ist WMI schon das richtige, auch wenn es natürlich für viel mehr verwendet werden kann.


  • Mod

    Vicious Falcon schrieb:

    Bist du denn sicher, dass du _unbedingt_ ein SAFEARRAY brauchst. Ich habe mir einmal die MSDN dazu angeschaut, das sieht ja furchtbar aus 😮 .
    Zumindest, wenn du C++ programmierst, hast du doch viel elegantere Möglichkeiten, Speicher anzufordern (ist aus deinem bisher geposteten Code nicht ersichtlich).

    Es gehtnicht darum wie man Speicher anfordert, sondern wie die COM Schnittstelle Arrays zurückgibt.
    Und das sind immer SafeArrays, wenn es um Automation geht!

    Zumindest für diesen Get erhält er einen VARIANT und in dem steckt ein SafeArray!


Anmelden zum Antworten