Partilhar via


Fazendo uma chamada assíncrona com VBScript

Fazer uma chamada assíncrona para um método WMI ou um método de provedor de permite que um script continue sendo executado enquanto os objetos retornam a um objeto SWbemSinke são manipulados por métodos como SWbemSink.OnObjectReady. No entanto, chamadas assíncronas não são recomendadas porque os dados podem não ser retornados no mesmo nível de segurança que a chamada é feita.

Ao usar chamadas de coletor assíncronas como SWbemSink.OnObjectReady para obter dados retornados, você pode definir o seguinte valor do Registro.

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WBEM\CIMOM\UnsecAppAccessControlDefault

A definição desse valor do Registro garante a autenticação dos objetos de dados retornados ao coletor. Se UnsecAppAccessControlDefault estiver definido como um (1), o WMI executará a verificação de acesso do retorno de dados. As verificações de acesso verificam se os dados vêm da fonte correta. Para obter mais informações, consulte Definindo a segurança em uma chamada assíncrona.

Métodos assíncronos com nomes que terminam em "Async_" sempre retornam imediatamente após serem chamados para que um programa possa continuar sendo executado. Por exemplo, SWbemServices.ExecQuery é síncrono e bloqueia a execução até que todos os objetos sejam retornados. O método SWbemServices.ExecQueryAsync é a versão assíncrona sem bloqueio. Uma maneira mais segura de fazer a chamada para SWbemServices.ExecQuery não bloqueando é fazendo com que a chamada de forma semissíncrona. Para obter mais informações, consulte Definindo a segurança em uma de chamada assíncrona e Fazendo uma chamada semissíncrona com o VBScript.

O parâmetro iFlags para chamadas assíncronas sempre tem como padrão zero (0). Os métodos assíncronos não fornecem uma coleção de SWbemObjectSet para a sub-rotina de sink. Em vez disso, o SWbemSink.OnObjectReady sub-rotina de eventos em seu script ou aplicativo recebe cada objeto conforme é fornecido.

Quando a chamada assíncrona original é concluída, ela chama o SWbemSink.OnCompleted evento do coletor de objetos e executa o código que você coloca lá para processar o resultado da chamada.

Observação

Um Ative Server Page (ASP) como um host de script não oferece suporte a uma chamada assíncrona.

 

O procedimento a seguir descreve como fazer uma chamada assíncrona usando VBScript.

Para fazer uma chamada assíncrona usando VBScript

  1. Conecte-se ao WMI e obtenha o objeto SWbemServices.

    Set Service = GetObject("Winmgmts:")
    
  2. Crie o coletor de objetos usando CreateObject ou (somente para Windows Script Host 2.0) o tag OBJECT com um atributo events definido como TRUE.

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

    -ou-

    <OBJECT progid="WbemScripting.SWbemSink" ID="SINK" events="true"/>
    
  3. Crie uma sub-rotina para cada evento que um evento assíncrono pode disparar. Esses eventos são definidos como métodos em SWbemObject. Por exemplo, o WMI efetua uma chamada de retorno para SWbemSink.OnObjectReady à medida que cada instância é devolvida.

    Ao criar a sub-rotina, coloque o código na sub-rotina para manipular cada evento quando ele for recebido.

    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
    

    Examine o parâmetro iHresult retornado pelo evento OnCompleted para determinar se a chamada assíncrona foi bem-sucedida ou se ocorreu um erro. Se for bem-sucedido, o valor passado no parâmetro iHresult será igual a zero (0). Qualquer outro valor pode indicar um erro, e você deve verificar os valores no objeto de erro que é retornado no objErrorObject parâmetro.

  4. Faça uma chamada assíncrona e passe o nome do coletor no parâmetro objWbemSink.

    Service.InstancesOfAsync sink, "Win32_process"
    
  5. Faça uma chamada que impeça que o script termine antes que todos os eventos sejam recebidos. Se o script pode ser executado com uma interface de tela, uma maneira simples de fazer isso é usar um comando Echo Windows Script Host (WSH), que é mostrado no exemplo a seguir.

    WScript.Echo "Waiting for instances."
    

    Quando executares este script, poderás ver a primeira instância retornar antes da mensagem Aguardando instâncias, ou poderás vê-la depois. Esta é a natureza do processamento assíncrono. Se você fechar a caixa de mensagem Aguardando instâncias muito cedo, talvez não veja todas as instâncias.

  6. Se tiver resultados de várias chamadas assíncronas diferentes retornando ao mesmo destino, armazene todos os dados distintivos necessários no parâmetro de contexto objWbemAsyncContext.

  7. Quando terminar com o lava-louças, cancele a sua chamada assíncrona com o método Cancel.

    objwbemsink.Cancel()
    

    O método Cancel instrui o WSH a cancelar todas as chamadas assíncronas associadas a um determinado objeto de coletor. Assim, convém usar coletores separados para operações assíncronas que devem ser independentes.

  8. Libere o objeto de sumidouro atribuindo o objeto de sumidouro a Nothing.

    set objwbemsink= Nothing
    

O exemplo de código a seguir mostra uma consulta assíncrona para todas as instâncias de Win32_Process na máquina local. Para obter uma versão semissíncrona do mesmo método, consulte Chamando um método.

' 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

Chamando um método

Manter a Segurança do WMI