Göra ett asynkront anrop med C++
WMI-program som skrivits i C++ kan göra asynkrona anrop med hjälp av många av metoderna i IWbemServices COM-gränssnittet. Den rekommenderade proceduren för att anropa en WMI-metod eller en providermetod är dock att använda semisynkrona anrop eftersom semisynkrona anrop är säkrare än asynkrona anrop. Mer information finns i Att göra ett semisynkront anrop med C++ och ställa in säkerhet på ett asynkront anrop.
Följande procedur beskriver hur du gör ett asynkront anrop genom att använda en sink i din process.
För att göra ett asynkront anrop med C++
Implementera gränssnittet IWbemObjectSink.
Alla program som gör asynkrona anrop måste implementera IWbemObjectSink. Tillfälliga händelseanvändare implementerar också IWbemObjectSink- för att ta emot meddelanden om händelser.
Logga in på WMI-målnamnområdet.
Program måste alltid anropa COM-funktionen CoInitializeSecurity under initieringsfasen. Om de inte gör det innan de gör ett asynkront anrop släpper WMI programmottagaren utan att slutföra det asynkrona anropet. För mer information, se Initialisera COM för en WMI-applikation.
Ställ in säkerheten för din diskho.
Asynkrona anrop skapar en mängd olika säkerhetsproblem som du kan behöva hantera, till exempel att tillåta WMI-åtkomst till ditt program. Mer information finns i Ställa in säkerhet på ett asynkront anrop.
Gör det asynkrona anropet.
Metoden returnerar omedelbart med WBEM_S_NO_ERROR framgångskod. Programmet kan fortsätta med andra uppgifter i väntan på att åtgärden ska slutföras. WMI rapporterar tillbaka till programmet genom att anropa metoder i IWbemObjectSink-implementeringen av ditt program.
Om det behövs kontrollerar du implementeringen regelbundet för uppdateringar.
Program kan ta emot meddelanden om mellanliggande status genom att ange parametern lFlags i det asynkrona anropet till WBEM_FLAG_SEND_STATUS. WMI rapporterar anropets status genom att ange parametern lFlags för IWbemObjectSink till WBEM_STATUS_PROGRESS.
Om det behövs kan du avbryta samtalet innan WMI slutför bearbetningen genom att anropa metoden IWbemServices::CancelCallAsync.
Metoden CancelAsyncCall avbryter asynkron bearbetning genom att omedelbart släppa pekaren till IWbemObjectSink--gränssnittet och garanterar att pekaren släpps innan CancelAsyncCall- returnerar.
Om du använder ett omslutningsobjekt som implementerar gränssnittet IUnsecured som värd för IWbemObjectSinkkan du hitta ytterligare komplikationer. Eftersom programmet måste skicka samma pekare till CancelAsyncCall- som skickades i det ursprungliga asynkrona anropet måste programmet hålla fast vid omslutningsobjektet tills det blir tydligt att annullering inte krävs. Mer information finns i Ställa in säkerhet på ett asynkront anrop.
När du är klar rensar du pekarna och stänger av programmet.
WMI tillhandahåller det slutliga statusanropet via metoden SetStatus.
Not
När den slutliga statusuppdateringen har skickats frigör WMI objektsänkan genom att anropa metoden Release för klassen som implementerar IWbemObjectSink- gränssnittet. I föregående exempel är detta metoden QuerySink::Release. Om du vill ha kontroll över mottagarobjektets livslängd kan du implementera mottagaren med ett inledande referensantal på en (1).
Om ett klientprogram skickar samma sink-gränssnitt i två olika överlappande asynkrona anrop garanterar WMI inte återanropens ordning. Ett klientprogram som gör överlappande asynkrona anrop bör antingen skicka olika mottagarobjekt eller serialisera anropen.
Följande exempel kräver följande referens- och #include-instruktioner.
#include <iostream>
using namespace std;
#pragma comment(lib, "wbemuuid.lib")
#include <wbemidl.h>
I följande exempel beskrivs hur du gör en asynkron fråga med hjälp av metoden ExecQueryAsync, men inte skapar säkerhetsinställningar eller släpper IWbemObjectSink-objektet. Mer information finns i Ställa in säkerhet på ett asynkront anrop.
// Set input parameters to ExecQueryAsync.
BSTR QueryLang = SysAllocString(L"WQL");
BSTR Query = SysAllocString(L"SELECT * FROM MyClass");
// Create IWbemObjectSink object and set pointer.
QuerySink *pSink = new QuerySink;
IWbemServices* pSvc = 0;
// Call ExecQueryAsync.
HRESULT hRes = pSvc->ExecQueryAsync(QueryLang,
Query,
0,
NULL,
pSink);
// Check for errors.
if (hRes)
{
printf("ExecQueryAsync failed with = 0x%X\n", hRes);
SysFreeString(QueryLang);
SysFreeString(Query);
delete pSink;
return ERROR;
}
Not
Koden ovan kompileras inte utan fel eftersom klassen QuerySink inte har definierats. Mer information om QuerySinkfinns i IWbemObjectSink.
Relaterade ämnen