Выполнение асинхронного вызова с помощью 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 приемника объекта и выполняется код, который вы размещаете там для обработки результата вызова.

Примечание

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

 

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

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

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

    Set Service = GetObject("Winmgmts:")
    
  2. Создайте приемник объекта с помощью CreateObject или (только для узла сценариев Windows 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). Любое другое значение может указывать на ошибку, и следует проверка значения в объекте error, возвращаемом в параметре objErrorObject.

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

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

    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