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

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

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

HKEY_LOCAL_MACHINE\ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ\Microsoft\WBEM\CIMOM\UnsecAppAccessControlDefault

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

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

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

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

Примечание

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

 

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

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

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

    Set Service = GetObject("Winmgmts:")
    
  2. Создайте приемник объекта с помощью CreateObject или (только для узла скриптов Windows 2.0) тег OBJECT с атрибутом событий, установленным равным 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. Выполните вызов, который предотвращает завершение скрипта до получения всех событий. Если скрипт может выполняться с помощью интерфейса экрана, простой способ сделать это — использовать команду узла скриптов Windows (WSHEcho), как показано в следующем примере.

    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