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 비블로킹을 호출하는 보다 안전한 방법은 호출을 반동기적으로 만드는 것입니다. 자세한 내용은 반동기적 호출에서 보안 설정VBScript로 반동기적 호출 만들기를 참조하세요.

비동기적 호출에 대한 iFlags 매개 변수는 항상 기본값을 0(영)으로 설정합니다. 비동기 메서드는 싱크 서브루틴에 SWbemObjectSet 컬렉션을 제공하지 않습니다. 대신 스크립트 또는 응용 프로그램의 SWbemSink.OnObjectReady 이벤트 서브루틴은 제공된 대로 각 개체를 받습니다.

원래 비동기 호출이 완료되면 개체 싱크의 SWbemSink.OnCompleted 이벤트를 호출하고, 배치한 코드를 실행하여 호출 결과를 처리합니다.

참고

스크립트 호스트로서의 ASP(Active Server Page)는 비동기 호출을 지원하지 않습니다.

 

다음 절차에서는 VBScript를 사용하여 비동기적 호출을 하는 방법을 설명합니다.

VBScript를 사용하여 비동기적 호출하기

  1. WMI에 연결하고 SWbemServices 개체를 가져옵니다.

    Set Service = GetObject("Winmgmts:")
    
  2. CreateObject 또는 이벤트 특성이 TRUE로 설정된 OBJECT 태그(Windows 스크립트 호스트 2.0에만 해당)를 사용하여 개체 싱크를 만듭니다.

    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
    

    OnCompleted 이벤트에서 반환된 iHresult 매개 변수를 검사하여 비동기 호출이 성공했는지 또는 오류가 발생했는지 여부를 확인합니다. 성공하면 iHresult 매개 변수에 전달된 값이 0과 같습니다. 다른 값은 오류를 나타낼 수 있으며 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 보안 유지 관리