Поделиться через


Выполнение асинхронного вызова с помощью VBScript

Выполнение асинхронного вызова метода WMI или метода поставщикапозволяет скрипту продолжать выполняться, пока объекты возвращаются к объекту SWbemSink и обрабатываются такими методами, как SWbemSink.OnObjectReady. Однако асинхронные вызовы не рекомендуются, так как данные могут быть возвращены не на том же уровне безопасности, как при вызове.

При использовании асинхронных вызовов приемника, таких как SWbemSink.OnObjectReady для получения возвращаемых данных, можно задать следующее значение реестра.

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WBEM\CIMOM\UnsecAppAccessControlDefault

Установка этого значения реестра гарантирует проверку подлинности объектов данных, возвращенных приемнику. Если UnsecAppAccessControlDefault имеет значение 1, WMI выполняет проверку доступа возвращаемых данных. Проверка доступа проверяет, поступает ли данные из правильного источника. Дополнительные сведения см. в разделе Настройка безопасности для асинхронного вызова.

Асинхронные методы с именами, заканчивающимися "Async_", всегда возвращаются сразу после вызова, чтобы программа продолжала выполняться. Например, SWbemServices.ExecQuery является синхронным и блокирует выполнение до возврата всех объектов. Метод SWbemServices.ExecQueryAsync — это неблокируемая асинхронная версия. Более безопасный способ сделать вызов SWbemServices.ExecQuery nonblocking заключается в том, что вызов полусинхронно. Дополнительные сведения см. в разделе Настройка безопасности для асинхронного вызова и создание полусинхронного вызова с помощьюVBScript.

Параметр iFlags для асинхронных вызовов всегда равен нулю (0) по умолчанию. Асинхронные методы не предоставляют субрутине-приемнику коллекцию SWbemObjectSet . Вместо этого SWbemSink.OnObjectReady в скрипте или приложении получает каждый объект по мере его предоставления.

После завершения первоначального асинхронного вызова вызывается событие SWbemSink.OnCompleted объектного приемника и выполняет размещённый там код для обработки результата вызова.

Заметка

Страница Active Server (ASP) в качестве узла скрипта не поддерживает асинхронный вызов.

 

В следующей процедуре описывается, как выполнить асинхронный вызов с помощью VBScript.

Для выполнения асинхронного вызова, используя VBScript

  1. Подключитесь к WMI и получите объект SWbemServices.

    Set Service = GetObject("Winmgmts:")
    
  2. Создайте приемник объекта с помощью CreateObject или (только для Windows Script Host 2.0) тег OBJECT с атрибутом events, установленным в значение TRUE.

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

    -или-

    <OBJECT progid="WbemScripting.SWbemSink" ID="SINK" events="true"/>
    
  3. Создайте подпрограмму для каждого события, которое может активировать асинхронное событие. Эти события определяются как методы SWbemObject. Например, WMI вызывает SWbemSink.OnObjectReady каждый раз, когда возвращается экземпляр.

    При создании подпрограммы поместите в неё код для обработки каждого события при его получении.

    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
    

    Проверьте параметр iHresult, возвращаемый событием OnCompleted, чтобы определить, выполнен ли асинхронный вызов или произошла ошибка. В случае успешного выполнения значение, переданное в параметре iHresult, равно нулю (0). Любое другое значение может указывать на ошибку, и необходимо проверить значения в объекте ошибки, возвращаемом в параметре objErrorObject.

  4. Выполните асинхронный вызов и передайте имя приемника в параметре objWbemSink.

    Service.InstancesOfAsync sink, "Win32_process"
    
  5. Сделайте вызов, который предотвращает завершение скрипта до получения всех событий. Если сценарий может выполняться с помощью интерфейса экрана, простой способ сделать это — использовать команду Echo узла скриптов Windows (WSH), которая показана в следующем примере.

    WScript.Echo "Waiting for instances."
    

    При выполнении этого скрипта вы можете увидеть первый экземпляр, возвращаемый до сообщения Ожидание экземпляров или после него. Это характер асинхронной обработки. Если слишком рано закрыть окно сообщения "ожидание экземпляров", вы можете не увидеть все экземпляры.

  6. Если у вас есть результаты нескольких разных асинхронных вызовов, возвращающихся в один приемник, сохраните все необходимые отличительные данные в параметре контекста objWbemAsyncContext.

  7. По завершении работы с приемником отмените асинхронный вызов с помощью метода Cancel.

    objwbemsink.Cancel()
    

    Метод Cancel указывает WSH отменить все асинхронные вызовы, связанные с заданным объектом-приемником. Таким образом, можно использовать отдельные обработчики для асинхронных операций, которые должны быть независимыми.

  8. Отпустите объект приемника, назначив объект приемника Nothing.

    set objwbemsink= Nothing
    

В следующем примере кода показан асинхронный запрос для всех экземпляров Win32_Process на локальном компьютере. Для полусинхронной версии того же метода см. в разделе "" "Вызов метода" "".

' 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

Вызов метода

Поддержание безопасности WMI