Fazer uma chamada assíncrona com VBScript

Fazer uma chamada assíncrona para um método WMI ou um método de provedor permite que um script continue em execução enquanto os objetos retornam a um objeto SWbemSink e 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

Definir esse valor do registro garante a autenticação dos objetos de dados retornados ao coletor. Se UnsecAppAccessControlDefault estiver definido como 1 (um), 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 Configurar a segurança em uma chamada assíncrona.

Métodos assíncronos com nomes que terminam em "Async_" são sempre retornados imediatamente após serem chamados para que um programa possa continuar em execução. 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 o desbloqueio de SWbemServices.ExecQuery é tornando a chamada semissíncrona. Para obter mais informações, consulte Configurar a segurança em uma chamada assíncrona e Fazer uma chamada semissíncrona com VBScript.

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

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

Observação

Uma ASP (Página do Servidor Ativo) como host de script não dá suporte a uma chamada assíncrona.

 

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

Para fazer uma chamada assíncrona usando VBScript

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

    Set Service = GetObject("Winmgmts:")
    
  2. Crie o coletor de objetos usando CreateObject ou (somente para o Windows Script Host 2.0) a marca OBJECT com um atributo de eventos 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 possa disparar. Esses eventos são definidos como métodos em SWbemObject. Por exemplo, o WMI faz um retorno de chamada para SWbemSink.OnObjectReady conforme cada instância é retornada.

    Ao criar a sub-rotina, coloque o código na sub-rotina para manipular cada evento quando 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-sucedida, o valor passado no parâmetro iHresult será igual a 0 (zero). Qualquer outro valor pode indicar um erro e você deve marcar os valores no objeto de erro retornados no parâmetro objErrorObject.

  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 puder ser executado com uma interface de tela, uma maneira simples de fazer isso é usar um comando Echo do WSH (Windows Script Host) que é mostrado no exemplo a seguir.

    WScript.Echo "Waiting for instances."
    

    Ao executar esse script, você poderá ver o retorno da primeira instância antes da mensagem Aguardando instâncias ou poderá vê-lo depois. Essa é 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 para o mesmo coletor, armazene todos os dados diferenciais necessários no parâmetro de contexto objWbemAsyncContext.

  7. Quando terminar com o coletor, cancele 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. Portanto, talvez você queira usar coletores separados para operações assíncronas que devem ser independentes.

  8. Solte o objeto de coletor atribuindo o objeto de coletor 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 no computador local. Para obter uma versão semissíncrona do mesmo método, consulte Chamar 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

Chamar um método

Manter a segurança do WMI