비동기 이벤트 알림 받기

비동기 이벤트 알림은 응용 프로그램이 시스템 리소스를 차지 않고도 이벤트를 지속적으로 모니터링할 수 있도록 하는 기술입니다. 비동기 이벤트 알림에는 다른 비동기 호출에 대 한 보안 제한 사항이 동일 합니다. 대신 동기 호출을 수행할 수 있습니다. 자세한 내용은 메서드 호출을 참조 하세요.

클라이언트로 라우팅되는 비동기 이벤트의 큐는 매우 커질 수 있습니다. 따라서 WMI는 메모리 부족을 방지 하기 위해 시스템 차원의 정책을 구현 합니다. WMI는 이벤트를 느려지거나 큐가 특정 크기를 초과 하는 경우 큐에서 이벤트를 삭제 하기 시작 합니다.

WMI는 Win32 _ WMISetting 클래스의 LowThresholdOnEventsHighThresholdOnEvents 속성을 사용 하 여 메모리 부족 방지에 대 한 제한을 설정 합니다. 최소값은 WMI에서 이벤트 알림 속도를 시작 해야 하는 시기를 나타내고 최대값은 이벤트 삭제를 시작할 시기를 나타냅니다. 낮은 임계값과 높은 임계값의 기본값은 100만 (10mb) 및 200만 (20mb)입니다. 또한 MaxWaitOnEvents 속성을 설정 하 여 WMI가 이벤트를 삭제 하기 전에 대기 해야 하는 시간을 설명할 수 있습니다. MaxWaitOnEvents 의 기본값은 2000 또는 2 초입니다.

VBScript에서 비동기 이벤트 알림 받기

이벤트 알림을 수신 하는 스크립팅 호출은 기본적으로 동일한 보안 문제가 있는 모든 비동기 호출과 동일 합니다. 자세한 내용은 VBScript를 사용 하 여 비동기 호출 만들기를 참조 하세요.

VBScript에서 비동기 이벤트 알림을 받으려면

  1. Wscript.exe 를 호출 하 고 "WbemScripting"의 Progid와 SWbemSink의 개체 형식을 지정 하 여 싱크 개체를 만듭니다. 싱크 개체가 알림을 받습니다.

  2. 처리 하려는 각 이벤트에 대해 서브루틴을 작성 합니다. 다음 표에서는 SWbemSink 이벤트를 나열 합니다.

    이벤트 의미
    OnObjectReady 싱크에 대 한 개체의 반환을 보고 합니다. 이 호출을 사용 하면 작업이 완료 될 때까지 매번 하나의 개체가 반환 됩니다.
    OnCompleted 비동기 호출이 완료 되 면 보고 합니다. 작업이 무한 하지 않으면이 이벤트는 발생 하지 않습니다.
    OnObjectPut 비동기 put 작업의 완료를 보고 합니다. 이 이벤트는 인스턴스의 개체 경로 또는 저장 된 클래스를 반환 합니다.
    OnProgress 진행 중인 비동기 호출의 상태를 보고 합니다. 모든 공급자가 중간 진행률 보고서를 지 원하는 것은 아닙니다.
    취소 이 개체 싱크와 관련 된 미해결 비동기 작업을 모두 취소 합니다.

다음 VBScript 코드 예제에서는 10 초 폴링 간격을 사용 하 여 프로세스 삭제를 알립니다. 이 스크립트에서 서브루틴 싱크 _ onobjectready는 이벤트 발생을 처리 합니다. 이 예제에서 싱크 개체의 이름은 "Sink" 이지만 사용자가 선택 하는 대로이 개체의 이름을 지정할 수 있습니다.

strComputer = "." 
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2") 
Set MySink = WScript.CreateObject( _
    "WbemScripting.SWbemSink","SINK_")

objWMIservice.ExecNotificationQueryAsync MySink, _
    "SELECT * FROM __InstanceDeletionEvent" _
    & " WITHIN 10 WHERE TargetInstance ISA 'Win32_Process'"


WScript.Echo "Waiting for events..."

While (True)
    Wscript.Sleep(1000)
Wend

Sub SINK_OnObjectReady(objObject, objAsyncContext)
    Wscript.Echo "__InstanceDeletionEvent event has occurred."
End Sub

Sub SINK_OnCompleted(objObject, objAsyncContext)
    WScript.Echo "Event call complete."
End Sub

C + +로 비동기 이벤트 알림 받기

비동기 알림을 수행 하려면 WMI(Windows Management Instrumentation) (WMI)에서 이벤트를 모니터링 하 고 수신 하기 위해서만 별도의 스레드를 만듭니다. 스레드가 메시지를 받으면 스레드에서 주 응용 프로그램에 알립니다.

별도의 스레드만 전용으로 이벤트 도착을 대기 하는 동안 다른 작업을 수행 하는 기본 프로세스를 허용 합니다. 알림의 비동기 배달이 성능을 향상 시키지만 원하는 것 보다 보안 수준이 떨어질 수 있습니다. C + +에서는 IWbemUnsecuredApartment 인터페이스를 사용 하거나 보안 설명자에 대 한 액세스 검사를 수행할 수 있습니다. 자세한 내용은 비동기 호출에 대 한 보안 설정을 참조 하세요.

비동기 이벤트 알림을 설정 하려면

  1. 비동기 알림을 초기화 하기 전에 Win32 _ WMISetting에서 메모리 부족 방지 매개 변수가 올바르게 설정 되어 있는지 확인 합니다.

  2. 수신 하려는 이벤트의 종류를 결정 합니다.

    WMI는 내장 및 외부 이벤트를 지원 합니다. 내장 이벤트는 WMI에 의해 미리 정의 된 이벤트 이지만 외부 이벤트는 타사 공급자가 정의 하는 이벤트입니다. 자세한 내용은 받을 이벤트 유형 확인을 참조 하세요.

다음 절차에서는 c + +로 비동기 이벤트 알림을 수신 하는 방법을 설명 합니다.

C + +로 비동기 이벤트 알림을 받으려면

  1. CoInitializeExCoInitializeSecurity 함수에 대 한 호출을 사용 하 여 응용 프로그램을 설정 합니다.

    CoInitializeEx 는 COM을 초기화 하는 반면, CoInitializeSecurity 는 WMI에 소비자 프로세스를 호출할 수 있는 권한을 부여 합니다. CoInitializeEx 함수는 또한 비동기 알림에 필요한 다중 스레드 응용 프로그램을 프로그래밍 하는 기능을 부여 합니다. 자세한 내용은 WMI 보안 유지 관리를 참조 하세요.

    이 항목의 코드를 사용 하려면 다음 참조와 # include 문을 올바르게 컴파일해야 합니다.

    #define _WIN32_DCOM
    #include <iostream>
    using namespace std;
    #include <wbemidl.h>
    

    다음 코드 예제에서는 CoInitializeExCoInitializeSecurity에 대 한 호출을 사용 하 여 임시 이벤트 소비자를 설정 하는 방법을 설명 합니다.

    void main(int argc, char **argv)
    {
        HRESULT hr = 0;
        hr = CoInitializeEx (0, COINIT_MULTITHREADED);
        hr = CoInitializeSecurity (NULL, 
           -1, 
           NULL, 
           NULL,   
           RPC_C_AUTHN_LEVEL_NONE, 
           RPC_C_IMP_LEVEL_IMPERSONATE, 
           NULL,
           EOAC_NONE,
           NULL); 
    
        if (FAILED(hr))
        {
           CoUninitialize();
           cout << "Failed to initialize security. Error code = 0x"
               << hex << hr << endl;
           return;
        }
    
    // ...
    }
    
  2. IWbemObjectSink 인터페이스를 통해 싱크 개체를 만듭니다.

    WMI는 IWbemObjectSink 을 사용 하 여 이벤트 알림을 보내고 비동기 작업 또는 이벤트 알림에서 상태를 보고 합니다.

  3. IWbemServices:: ExecNotificationQueryAsync 메서드에 대 한 호출을 사용 하 여 이벤트 소비자를 등록 합니다.

    PResponseHandler 매개 변수는 이전 단계에서 만든 싱크 개체를 가리키는지 확인 합니다.

    등록 목적은 필요한 알림만 수신 하는 것입니다. 불필요 한 알림을 받으면 처리 및 배달 시간이 낭비 됩니다. 및는 WMI의 필터링 기능을 최대한 활용 하지 않습니다.

    그러나 임시 소비자는 둘 이상의 이벤트 유형을 받을 수 있습니다. 이 경우 임시 소비자는 각 이벤트 형식에 대해 IWbemServices:: ExecNotificationQueryAsync 에 대 한 별도의 호출을 수행 해야 합니다. 예를 들어 새 프로세스를 만들 때 (인스턴스 생성 이벤트 또는 _ _ InstanceCreationEvent) 특정 레지스트리 키 ( RegistryKeyChangeEvent와 같은 레지스트리 이벤트)를 변경할 때 소비자에 게 알림이 필요할 수 있습니다. 따라서 소비자는 인스턴스 생성 이벤트를 등록 하 고 ExecNotificationQueryAsync 에 대 한 다른 호출을 수행 하 여 레지스트리 이벤트를 등록 하도록 ExecNotificationQueryAsync 를 한 번 호출 합니다.

    여러 이벤트를 등록 하는 이벤트 소비자를 만들도록 선택 하는 경우 동일한 싱크로 여러 클래스를 등록 하지 않아야 합니다. 대신 등록 된 이벤트의 각 클래스에 대해 별도의 싱크를 사용 합니다. 전용 싱크를 사용 하면 처리를 간소화 하 고 유지 관리를 지원 하므로 다른 사용자에 게 영향을 주지 않고 하나의 등록을 취소할 수 있습니다.

  4. 이벤트 소비자에서 필요한 작업을 수행 합니다.

    이 단계에서는 대부분의 코드를 포함 해야 하며 사용자 인터페이스에 이벤트를 표시 하는 것과 같은 작업을 포함 해야 합니다.

  5. 완료 되 면 IWbemServices:: CancelAsyncCall 이벤트를 호출 하 여 임시 이벤트 소비자를 등록 취소 합니다.

    Cancelasynccall 호출에 성공 또는 실패 여부에 관계 없이 개체 참조 수가 0에 도달할 때까지 싱크 개체를 삭제 하지 마십시오. 자세한 내용은 메서드 호출을 참조 하세요.