Ta emot asynkrona händelsemeddelanden
Asynkrona händelsemeddelanden är en teknik som gör att ett program ständigt kan övervaka händelser utan att monopolisera systemresurser. Asynkrona händelsemeddelanden har samma säkerhetsbegränsningar som andra asynkrona anrop har. Du kan göra semisynkrona anrop i stället. För mer information, se Anropa en metod.
Kön med asynkrona händelser som dirigeras till en klient kan bli exceptionellt stor. Därför implementerar WMI en systemomfattande princip för att undvika att minnet börjar ta slut. WMI saktar antingen ned händelser eller börjar släppa händelser från kön när kön växer över en viss storlek.
WMI använder egenskaperna LowThresholdOnEvents och HighThresholdOnEvents i klassen Win32_WMISetting för att ange gränser för att undvika minnesbrist. Det minsta värdet anger när WMI ska börja sakta ned händelsemeddelandet, och det maximala värdet anger när händelser ska börja tas bort. Standardvärdena för de låga och höga tröskelvärdena är 1000000 (10 MB) och 2000000 (20 MB). Dessutom kan du ange egenskapen MaxWaitOnEvents för att beskriva hur lång tid WMI ska vänta innan händelser tas bort. Standardvärdet för MaxWaitOnEvents är 2 000 eller 2 sekunder.
Ta emot asynkrona händelsemeddelanden i VBScript
Skriptanropen för att ta emot händelsemeddelanden är i stort sett desamma som alla asynkrona anrop med samma säkerhetsproblem. Mer information finns i Att göra ett asynkront anrop med VBScript-.
Ta emot asynkrona händelsemeddelanden i VBScript-
Skapa ett mottagarobjekt genom att anropa WScript.CreateObject och ange progid för "WbemScripting" och objekttypen SWbemSink. Sinkobjektet tar emot meddelandena.
Skriv en underrutin för varje händelse som du vill hantera. I följande tabell visas SWbemSink-händelser.
Händelse Betydelse OnObjectReady Rapporterar återlämnandet av ett objekt till mottagaren. Med det här anropet returneras ett objekt varje gång tills åtgärden har slutförts. OnCompleted Rapporterar när ett asynkront anrop är klart. Den här händelsen inträffar aldrig om åtgärden är obestämd. OnObjectPut Rapporterar slutförandet av en asynkron put-åtgärd. Den här händelsen returnerar objektsökvägen för instansen eller den sparade klassen. OnProgress Rapporterar status för ett asynkront anrop som pågår. Alla leverantörer stöder inte interimistiska förloppsrapporter. Avbryt Avbryter alla utestående asynkrona åtgärder som är associerade med objektmottagaren.
Följande VBScript-kodexempel meddelar borttagningen av processer med 10 sekunders avsökningsintervall. I det här skriptet hanterar SINK_OnObjectReady händelsehändelsen. I exemplet heter sinkobjektet "Sink", men du kan namnge detta objekt på valfritt sätt.
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
Ta emot asynkrona händelsemeddelanden i C++
För att utföra asynkrona meddelanden skapar du en separat tråd enbart för att övervaka och ta emot händelser från Windows Management Instrumentation (WMI). När tråden tar emot ett meddelande meddelar tråden huvudprogrammet.
Genom att avdela en separat tråd möjliggör du för huvudprocessen att utföra andra aktiviteter medan du väntar på att en händelse ska inträffa. Asynkron leverans av meddelanden förbättrar prestandan men kan ge mindre säkerhet än du vill. I C++kan du använda IWbemUnsecuredApartment-gränssnittet eller utföra åtkomstkontroller på säkerhetsbeskrivningar. Mer information finns i Ställa in säkerhet på ett asynkront anrop.
Konfigurera asynkrona händelsemeddelanden
Innan du initierar asynkrona meddelanden kontrollerar du att parametrarna för att undvika minnesbrist är korrekt inställda i Win32_WMISetting.
Ta reda på vilken typ av händelser du vill ta emot.
WMI stöder intrinsiska och extrinsiska händelser. En inneboende händelse är en händelse som är fördefinierad av WMI, medan en extern händelse är en händelse som definieras av en tredjepartsleverantör. Mer information finns i Fastställa vilken typ av händelse som ska ta emot.
Följande procedur beskriver hur du tar emot asynkrona händelseaviseringar i C++.
Ta emot asynkrona händelseaviseringar i C++
Konfigurera ditt program med anrop till funktionerna CoInitializeEx och CoInitializeSecurity.
Att anropa CoInitializeEx initierar COM, medan CoInitializeSecurity ger WMI behörighet att anropa konsumentens process. Funktionen CoInitializeEx ger dig också möjlighet att programmera ett flertrådat program, vilket är nödvändigt för asynkrona meddelanden. För mer information, se Underhåll av WMI-säkerhet.
Koden i det här avsnittet kräver följande referenser och #include-instruktioner för att kompilera korrekt.
#define _WIN32_DCOM #include <iostream> using namespace std; #include <wbemidl.h>
I följande kodexempel beskrivs hur du konfigurerar den tillfälliga händelsekonsumenten med anrop till CoInitializeEx och 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; } // ... }
Skapa ett mottagarobjekt via gränssnittet IWbemObjectSink.
WMI använder IWbemObjectSink för att skicka händelsemeddelanden och rapportera status för en asynkron åtgärd eller händelseavisering.
Registrera din händelsekonsument med ett anrop till metoden IWbemServices::ExecNotificationQueryAsync.
Kontrollera att pResponseHandler-parametern pekar på det mottagarobjekt som skapades i föregående steg.
Syftet med registreringen är att endast ta emot de meddelanden som krävs. Att ta emot överflödiga meddelanden slösar bearbetning och leveranstid; och använder inte filtreringsförmågan för WMI till största möjliga potential.
En tillfällig konsument kan dock ta emot mer än en typ av händelse. I det här fallet måste en tillfällig konsument göra separata anrop till IWbemServices::ExecNotificationQueryAsync för varje händelsetyp. En konsument kan till exempel behöva meddelas när nya processer skapas (en händelse för att skapa en instans eller __InstanceCreationEvent) och för ändringar i vissa registernycklar (en registerhändelse som RegistryKeyChangeEvent). Därför gör konsumenten ett anrop till ExecNotificationQueryAsync för att registrera sig för instansskapandehändelser och ett annat anrop till ExecNotificationQueryAsync att registrera sig för registerhändelser.
Om du väljer att skapa en händelsekonsument som registrerar sig för flera händelser bör du undvika att registrera flera klasser med samma mottagare. Använd i stället en separat mottagare för varje klass av registrerad händelse. Att ha en dedikerad diskho förenklar bearbetning och underhåll, så att du kan avbryta en registrering utan att påverka de andra.
Utför nödvändiga aktiviteter i din händelsekonsument.
Det här steget bör innehålla det mesta av koden och inkludera aktiviteter som att visa händelser i ett användargränssnitt.
När du är klar avregistrerar du den tillfälliga händelsekonsumenten med ett anrop till händelsen IWbemServices::CancelAsyncCall.
Oavsett om anropet till CancelAsyncCall lyckas eller misslyckas ska du inte ta bort mottagarobjektet förrän antalet objektreferenser når noll. För mer information, se Anropa en metod.