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
Conecte-se ao WMI e obtenha um objeto SWbemServices .
Set Service = GetObject("Winmgmts:")
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"/>
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.
Faça uma chamada assíncrona e passe o nome do coletor no parâmetro objWbemSink.
Service.InstancesOfAsync sink, "Win32_process"
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.
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.
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.
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
Tópicos relacionados