WMI und wmiprvse.exe



  • Hallo.

    Ich nutze in einem C/C++ Programm die Dineste von Windows Management Instrumentation.
    Damit lese ich nun zum Beipiel die vielen Informationend er Klasse "Win32_SoftwareElement" aus. Direkt nach dem ausführen der Abfrage für die ganzen Objekte

    //IWbemServices *pSvc wurde vorher bereits korrekt initialisert
    
    HRESULT hRes;
    IEnumWbemClassObject *pEnumerator = NULL;
    std::string sClassString = "SELECT * FROM Win32_SoftwareElement";
    
    	hRes = pSvc->ExecQuery(
    		bstr_t("WQL"),
    		bstr_t(sClassString.c_str()),
    		WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
    		NULL,
    		&pEnumerator
    		);
    

    startet dann der Dienst wmiprvse.exe mit ca 50% CPU Auslastung. Wenn ich dann alle Objekte und Informationen abgefragt habe und letztendlich mein Programm beendet wird, läuft die wmiprvse.exe weiter. Weiterhin mit ca 50% CPU Auslastung und um die 60MB Speicher.

    Wodurch kommt das? Warum wir dieser dienst nicht bei allen WMI Klassen Aufgerufen und am wichtigsten für mich, warum beendet sich dieser Dienst nicht wieder wenn ich mein Programm beende?

    Ich find komm dae infach nicht weiter. Die Release() Funktion wird für pSvc und pEnumerator immer korrekt aufgreufen soweit ich das beim debuggen verfolgen konnte.

    Ich freue mich auf jede Hilfe.



  • oneill5000 schrieb:

    Die Release() Funktion wird für pSvc und pEnumerator immer korrekt aufgreufen soweit ich das beim debuggen verfolgen konnte.

    Bist Du Dir da sicher? Gerade hier passieren einem WMI-Einsteiger (wie auch damals bei mir 🙄 ) viele Flüchtigkeitsfehler.
    BTW: Sämtlich übermittelte COM-Strings (einschließlich VARIANT's) mußt Du auch wieder freigeben!

    Die WMI-Klasse "Win32_SoftwareElement" hat je nach PC eine riesige Elemente-Auflistung. Dazu kommt noch daß Du hier mit

    oneill5000 schrieb:

    "SELECT * FROM Win32_SoftwareElement"

    eine skriptähnliche Filterfunktion verwendest, somit kostet es logischerweise zusätzlich Rechenzeit 😮

    Martin



  • Danke für deine schnelle Antwort.

    Ich kann es ja nochmal durch gehen. Alle Variants gebe ich auch wieder frei ja. All das naürlich auch im Fehlerfall. Was genau meinst du mit COM Strings?

    Jetzt habe ich bemerkt, dass wenn mein Programm beenet wird, kurze Zeit später auch wmiprvse.exe wieder auf ca 0% CPU Leistung runter geht und dann auch beendet.
    Ist das nun richtig, dass das erst kurze Zeit nach beenden meines Programms geschieht, oder müsst es sofort passieren wenn ich alle Release(), etc. gemacht habe?



  • oneill5000 schrieb:

    Warum wir dieser dienst nicht bei allen WMI Klassen Aufgerufen

    Habe eben bei meinen Applikationen (die WMI nutzen) nachgesehen: Der Dienst wmiprvse.exe wird bei mir offensichtlich nicht gestartet.

    Es kann aber auch sein, daß dies abhängig von den verwendeten WMI-Klassen ist. Und höchstwahrscheinlich ist es auch davon abhängig ob Du die WMI-Klassen lokal oder per remote auf einem anderen Rechner nutzt. (reine Vermutung meinerseits)
    Ich verwende WMI ausschließlich für lokale Hardware-Informationen wie serielle Ports usw.

    Unter COM-Strings (oder auch "OLE Strings" or "Basic Strings") meine ich pauschal alles was mit dem Datentypen _bstr_t oder auch CComBSTR zu tun hat.
    Hintergrund: Jedes COM-Objekt (Properties, ... ) hat einen Referenzzähler, der mit jedem allokieren erhöht wird und mit Release() erniedrigt wird. Erst wenn dieser Referenzzähler den Wert 0 erreicht hat, wird der Speicher entweder sofort oder auch später freigegeben.
    Wenn ich mich nicht irre: Es steht nämlich nirgendwo geschrieben, daß die entsprechende COM-Klasse den Speicher sofort freigeben soll/muß wenn der Zähler bei 0 angekommen ist.
    Vielleicht ist das eine mögliche Erklärung für Deine Beobachtungen mit verspätetem Beenden von wmiprvse.exe?

    Martin

    [Nachtrag:] Irrtum: Bei mir wird doch wmiprvse.exe gestartet (Process Explorer ist da gnadenlos 🕶 ) und erst nach einigen Sekunden nach Programmende auch beendet. Die Speicherauslastung des Dienstes beträgt bei mir ca 7 MByte.
    Scheint also ganz normal zu sein.

    Vielleicht kann uns da ein anderer hier weiterhelfen?


Log in to reply