Esecuzione di una chiamata asincrona con VBScript

L'esecuzione di una chiamata asincrona a un metodo WMI o a un metodo provider consente a uno script di continuare l'esecuzione mentre gli oggetti restituiscono un oggetto SWbemSink e vengono gestiti da metodi come SWbemSink.OnObjectReady. Tuttavia, le chiamate asincrone non sono consigliate perché i dati potrebbero non essere restituiti allo stesso livello di sicurezza della chiamata eseguita.

Quando si usano chiamate sink asincrone come SWbemSink.OnObjectReady per ottenere i dati restituiti, è possibile impostare il valore del Registro di sistema seguente.

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WBEM\CIMOM\UnsecAppAccessControlDefault

L'impostazione di questo valore del Registro di sistema garantisce l'autenticazione degli oggetti dati restituiti al sink. Se UnsecAppAccessControlDefault è impostato su uno (1), WMI esegue il controllo di accesso dei dati restituiti. I controlli di accesso verificano che i dati provengano dall'origine corretta. Per altre informazioni, vedere Impostazione della sicurezza in una chiamata asincrona.

I metodi asincroni con nomi che terminano in "Async_" restituiscono sempre immediatamente dopo la chiamata in modo che un programma possa continuare l'esecuzione. Ad esempio, SWbemServices.ExecQuery è sincrono e blocca l'esecuzione finché non vengono restituiti tutti gli oggetti. Il metodo SWbemServices.ExecQueryAsync è la versione asincrona non bloccante. Un modo più sicuro per effettuare la chiamata a SWbemServices.ExecQuery nonblocking consiste nell'effettuare la chiamata in modo semisynchronous. Per altre informazioni, vedere Impostazione della sicurezza in una chiamata asincrona ed Esecuzione di una chiamata semisynchrono con VBScript.

Il parametro iFlags per le chiamate asincrone viene sempre impostato su zero (0). I metodi asincroni non forniscono una raccolta SWbemObjectSet alla subroutine sink. Al contrario, la subroutine dell'evento SWbemSink.OnObjectReady nello script o nell'applicazione riceve ogni oggetto fornito.

Al termine della chiamata asincrona originale, chiama l'evento SWbemSink.OnCompleted del sink dell'oggetto ed esegue il codice inserito per elaborare il risultato della chiamata.

Nota

Una pagina Asp (Active Server) come host di script non supporta una chiamata asincrona.

 

La procedura seguente descrive come effettuare una chiamata asincrona usando VBScript.

Per effettuare una chiamata asincrona tramite VBScript

  1. Connettersi a WMI e ottenere un oggetto SWbemServices .

    Set Service = GetObject("Winmgmts:")
    
  2. Creare il sink dell'oggetto usando CreateObject o (solo per Windows Script Host 2.0) il tag OBJECT con un attributo events impostato su TRUE.

    Set sink = WScript.CreateObject("WbemScripting.SWbemSink","SINK_")
    

    -oppure-

    <OBJECT progid="WbemScripting.SWbemSink" ID="SINK" events="true"/>
    
  3. Creare una subroutine per ogni evento che un evento asincrono può attivare. Questi eventi vengono definiti come metodi in SWbemObject. WMI, ad esempio, esegue un callback a SWbemSink.OnObjectReady quando viene restituita ogni istanza.

    Quando si crea la subroutine, inserire il codice nella subroutine per gestire ogni evento quando viene ricevuto.

    Sub SINK_OnCompleted(
          iHResult, 
          objErrorObject, 
          objAsyncContext
          )
        WScript.Echo "Asynchronous operation is done."
    End Sub
    
    Sub SINK_OnObjectReady(objObject, objAsyncContext)
        WScript.Echo (objObject.Name)
    End Sub
    

    Esaminare il parametro iHresult restituito dall'evento OnCompleted per determinare se la chiamata asincrona ha esito positivo o negativo o se si è verificato un errore. In caso di esito positivo, il valore passato nel parametro iHresult è uguale a zero (0). Qualsiasi altro valore può indicare un errore ed è necessario controllare i valori nell'oggetto error restituito nel parametro objErrorObject .

  4. Effettuare una chiamata asincrona e passare il nome del sink nel parametro objWbemSink .

    Service.InstancesOfAsync sink, "Win32_process"
    
  5. Effettuare una chiamata che impedisce la fine dello script prima della ricezione di tutti gli eventi. Se lo script può essere eseguito con un'interfaccia dello schermo, un modo semplice per eseguire questa operazione consiste nell'usare un comando Windows Script Host (WSH), Echo illustrato nell'esempio seguente.

    WScript.Echo "Waiting for instances."
    

    Quando si esegue questo script, è possibile che venga visualizzata la prima istanza restituita prima del messaggio In attesa di istanze o dopo. Questa è la natura dell'elaborazione asincrona. Se si chiude la finestra di messaggio Attesa istanze troppo presto, è possibile che non vengano visualizzate tutte le istanze.

  6. Se si ottengono risultati da diverse chiamate asincrone che tornano allo stesso sink, archiviare i dati di distinzione necessari nel parametro di contesto objWbemAsyncContext .

  7. Al termine del sink, annullare la chiamata asincrona con il metodo Cancel .

    objwbemsink.Cancel()
    

    Il metodo Cancel indica a WSH di annullare tutte le chiamate asincrone associate a un determinato oggetto sink. Pertanto, è possibile usare sink separati per le operazioni asincrone che devono essere indipendenti.

  8. Rilasciare l'oggetto sink assegnando l'oggetto sink a Nothing.

    set objwbemsink= Nothing
    

Nell'esempio di codice seguente viene illustrata una query asincrona per tutte le istanze di Win32_Process nel computer locale. Per una versione semiincrona dello stesso metodo, vedere Chiamata di un metodo.

' Create an object sink
set oSink = WScript.CreateObject("wbemscripting.swbemsink","sink_")
' Connect to WMI and the cimv2 namespace, and obtain
' an SWbemServices object
set oSvc = GetObject("winmgmts:root\cimv2")

bdone = false
' Query for all Win32_Process objects
osvc.ExecQueryAsync oSink, "SELECT Name FROM Win32_Process"
' Wait until all instances are returned. 
' The bdone flag prevents the script from exiting until
' the sink.OnCompleted subroutine is executed when
' all the objects are returned.
while not bdone    
    wscript.sleep 1000
wend

' The sink subroutine to handle the OnObjectReady 
' event. This is called as each object returns.
sub sink_OnObjectReady(oInst, octx)
    WScript.Echo "Got Instance: " & oInst.Name
end sub
' The sink subroutine to handle the OnCompleted event.
' This is called when all the objects are returned. 
' The oErr parameter obtains an SWbemLastError object,
' if available from the provider.
sub sink_OnCompleted(HResult, oErr, oCtx)
    WScript.Echo "ExecQueryAsync completed"
    bdone = true
end sub

Chiamata di un metodo

Gestione della sicurezza WMI