Delen via


Asynchrone gebeurtenismeldingen ontvangen

Asynchrone gebeurtenismelding is een techniek waarmee een toepassing voortdurend gebeurtenissen kan bewaken zonder systeembronnen te beheersen. Asynchrone gebeurtenismeldingen hebben dezelfde beveiligingsbeperkingen als andere asynchrone aanroepen. U kunt in plaats daarvan semisynchrone aanroepen uitvoeren. Zie Een methode aanroepenvoor meer informatie.

De wachtrij met asynchrone gebeurtenissen die naar een client worden gerouteerd, kan uitzonderlijk groot worden. WMI implementeert daarom een systeembreed beleid om te voorkomen dat er onvoldoende geheugen beschikbaar is. WMI vertraagt gebeurtenissen of begint met het verwijderen van gebeurtenissen uit de wachtrij wanneer de wachtrij voorbij een bepaalde grootte groeit.

WMI maakt gebruik van de LowThresholdOnEvents en HighThresholdOnEvents eigenschappen van de klasse Win32_WMISetting om limieten in te stellen voor het vermijden van onvoldoende geheugen. De minimumwaarde geeft aan wanneer WMI de gebeurtenismelding moet vertragen en de maximumwaarde geeft aan wanneer er gebeurtenissen moeten worden verwijderd. De standaardwaarden voor de lage en hoge drempelwaarden zijn 10000000 (10 MB) en 2000000 (20 MB). Daarnaast kunt u de eigenschap MaxWaitOnEvents instellen om te beschrijven hoe lang WMI moet wachten voordat gebeurtenissen worden neergezet. De standaardwaarde voor MaxWaitOnEvents is 2000 of 2 seconden.

Asynchrone gebeurtenismeldingen ontvangen in VBScript

De scriptaanroepen voor het ontvangen van gebeurtenismeldingen zijn in wezen hetzelfde als alle asynchrone aanroepen met dezelfde beveiligingsproblemen. Zie Een asynchrone aanroep maken met VBScriptvoor meer informatie.

Asynchrone gebeurtenismeldingen ontvangen in VBScript-

  1. Maak een sinkobject door WScript.CreateObject- aan te roepen en de opdracht 'WbemScripting' en het objecttype van SWbemSinkop te geven. Het sink-object ontvangt de meldingen.

  2. Schrijf een subroutine voor elke gebeurtenis die u wilt verwerken. De volgende tabel bevat de gebeurtenissen SWbemSink.

    Gebeurtenis Betekenis
    OnObjectReady Rapporteert de terugkeer van een object naar de doel. Met deze aanroep wordt telkens één object geretourneerd totdat de bewerking is voltooid.
    OnCompleted Rapporteert wanneer een asynchrone aanroep is voltooid. Deze gebeurtenis treedt nooit op als de bewerking voor onbepaalde tijd is.
    OnObjectPut Rapporteert de voltooiing van een asynchrone putbewerking. Met deze gebeurtenis wordt het objectpad van het exemplaar of de opgeslagen klasse geretourneerd.
    OnProgress Rapporteert de status van een asynchrone aanroep die wordt uitgevoerd. Niet alle providers ondersteunen tussentijdse voortgangsrapporten.
    annuleren Hiermee annuleert u alle openstaande asynchrone bewerkingen die zijn gekoppeld aan deze object sink.

     

In het volgende VBScript-codevoorbeeld wordt het verwijderen van processen gemeld met een interval van 10 seconden. In dit script verwerkt de subroutine SINK_OnObjectReady het optreden van de gebeurtenis. In het voorbeeld heet het sink-object 'Sink', maar u kunt dit object een naam opgeven zoals u kiest.

strComputer = "." 
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2") 
Set MySink = WScript.CreateObject( _
    "WbemScripting.SWbemSink","SINK_")

objWMIservice.ExecNotificationQueryAsync MySink, _
    "SELECT * FROM __InstanceDeletionEvent" _
    & " WITHIN 10 WHERE TargetInstance ISA 'Win32_Process'"


WScript.Echo "Waiting for events..."

While (True)
    Wscript.Sleep(1000)
Wend

Sub SINK_OnObjectReady(objObject, objAsyncContext)
    Wscript.Echo "__InstanceDeletionEvent event has occurred."
End Sub

Sub SINK_OnCompleted(objObject, objAsyncContext)
    WScript.Echo "Event call complete."
End Sub

Asynchrone gebeurtenismeldingen ontvangen in C++

Als u asynchrone meldingen wilt uitvoeren, maakt u alleen een afzonderlijke thread om gebeurtenissen van Windows Management Instrumentation (WMI) te bewaken en te ontvangen. Wanneer deze thread een bericht ontvangt, stelt de thread uw hoofdtoepassing op de hoogte.

Door een afzonderlijke thread toe te wijzen, kan het hoofdproces andere activiteiten uitvoeren terwijl het wacht tot een gebeurtenis binnenkomt. Asynchrone levering van meldingen verbetert de prestaties, maar biedt mogelijk minder beveiliging dan u wilt. In C++kunt u de IWbemUnsecuredApartment interface gebruiken of toegangscontroles uitvoeren op beveiligingsdescriptors. Zie Beveiliging instellen voor een Asynchrone aanroepvoor meer informatie.

Asynchrone gebeurtenismeldingen instellen

  1. Voordat u asynchrone meldingen initialiseert, moet u ervoor zorgen dat uw parameters voor het vermijden van geheugenuitval correct zijn ingesteld in Win32_WMISetting.

  2. Bepaal wat voor soort gebeurtenissen u wilt ontvangen.

    WMI ondersteunt intrinsieke en extrinsische gebeurtenissen. Een intrinsieke gebeurtenis is een gebeurtenis die vooraf is gedefinieerd door WMI, terwijl een extrinsische gebeurtenis een gebeurtenis is die is gedefinieerd door een externe provider. Zie Bepalen welk type gebeurtenis moet worden ontvangenvoor meer informatie.

In de volgende procedure wordt beschreven hoe u asynchrone gebeurtenismeldingen ontvangt in C++.

Asynchrone gebeurtenismeldingen ontvangen in C++

  1. Stel uw toepassing in met aanroepen naar de functies CoInitializeEx en CoInitializeSecurity.

    Het aanroepen van CoInitializeEx initialiseert COM, terwijl CoInitializeSecurity WMI toestemming verleent om het proces van de consument aan te roepen. De functie CoInitializeEx biedt u ook de mogelijkheid om een multithreaded toepassing te programmeren, die nodig is voor asynchrone meldingen. Zie WMI-beveiliging onderhoudenvoor meer informatie.

    De code in dit onderwerp vereist de volgende verwijzingen en #include instructies om correct te compileren.

    #define _WIN32_DCOM
    #include <iostream>
    using namespace std;
    #include <wbemidl.h>
    

    In het volgende codevoorbeeld wordt beschreven hoe u de tijdelijke gebeurtenisconsumer instelt met aanroepen naar CoInitializeEx en CoInitializeSecurity.

    void main(int argc, char **argv)
    {
        HRESULT hr = 0;
        hr = CoInitializeEx (0, COINIT_MULTITHREADED);
        hr = CoInitializeSecurity (NULL, 
           -1, 
           NULL, 
           NULL,   
           RPC_C_AUTHN_LEVEL_NONE, 
           RPC_C_IMP_LEVEL_IMPERSONATE, 
           NULL,
           EOAC_NONE,
           NULL); 
    
        if (FAILED(hr))
        {
           CoUninitialize();
           cout << "Failed to initialize security. Error code = 0x"
               << hex << hr << endl;
           return;
        }
    
    // ...
    }
    
  2. Maak een sinkobject via de interface IWbemObjectSink.

    WMI maakt gebruik van IWbemObjectSink- voor het verzenden van gebeurtenismeldingen en het rapporteren van de status van een asynchrone bewerking of gebeurtenismelding.

  3. Registreer uw gebeurtenisconsumer met een aanroep naar de methode IWbemServices::ExecNotificationQueryAsync.

    Zorg ervoor dat de parameter pResponseHandler verwijst naar het sinkobject dat u in de vorige stap hebt gemaakt.

    Het doel van registratie is om alleen de vereiste meldingen te ontvangen. Het ontvangen van overbodige meldingen verspilt verwerking en levertijd; en maakt geen gebruik van de filtermogelijkheid van WMI voor het volledige potentieel.

    Een tijdelijke consument kan echter meer dan één type gebeurtenis ontvangen. In dit geval moet een tijdelijke consument afzonderlijke aanroepen uitvoeren naar IWbemServices::ExecNotificationQueryAsync voor elk gebeurtenistype. Een consument kan bijvoorbeeld een melding vereisen wanneer nieuwe processen worden gemaakt (een gebeurtenis voor het maken van een exemplaar of __InstanceCreationEvent) en voor wijzigingen in bepaalde registersleutels (een registergebeurtenis zoals RegistryKeyChangeEvent). Daarom doet de gebruiker één aanroep naar ExecNotificationQueryAsync voor het registreren van exemplaarcreatiegebeurtenissen en een andere aanroep naar ExecNotificationQueryAsync om registergebeurtenissen te registreren.

    Als u ervoor kiest om een gebeurtenisconsumer te maken die zich registreert voor meerdere gebeurtenissen, moet u voorkomen dat u meerdere klassen bij dezelfde sink registreert. Gebruik in plaats daarvan een afzonderlijke sink voor elke klasse van de geregistreerde gebeurtenissen. Het hebben van een speciale spoelbak vereenvoudigt de verwerking en helpt bij het onderhoud, zodat u een registratie kunt annuleren zonder dat dit invloed heeft op de andere.

  4. Voer alle noodzakelijke activiteiten uit in uw event consumer.

    Deze stap moet het grootste deel van uw code bevatten en dergelijke activiteiten bevatten, zoals het weergeven van gebeurtenissen in een gebruikersinterface.

  5. Wanneer u klaar bent, moet u de registratie van de tijdelijke gebeurtenisgebruiker ongedaan maken met een aanroep naar de IWbemServices::CancelAsyncCall gebeurtenis.

    Ongeacht of de aanroep naar CancelAsyncCall slaagt of mislukt, verwijdert u het sinkobject pas als het aantal objectverwijzingen nul bereikt. Zie Een methode aanroepenvoor meer informatie.