Partilhar via


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