비동기 이벤트 알림 수신
비동기 이벤트 알림은 애플리케이션이 시스템 리소스를 독점하지 않고도 이벤트를 지속적으로 모니터링할 수 있는 기술입니다. 비동기 이벤트 알림에는 다른 비동기 호출과 동일한 보안 제한이 있습니다. 대신 준동기 호출을 수행할 수 있습니다. 자세한 내용은 메서드호출을 참조하세요.
클라이언트로 라우팅되는 비동기 이벤트의 큐는 매우 커질 가능성이 있습니다. 따라서 WMI는 메모리 부족이 발생하지 않도록 시스템 차원의 정책을 구현합니다. WMI는 이벤트를 느리게 하거나 큐가 특정 크기를 초과할 때 큐에서 이벤트를 삭제하기 시작합니다.
WMI는 Win32_WMISetting 클래스의 LowThresholdOnEvents 및 HighThresholdOnEvents 속성을 사용하여 메모리 부족 방지에 대한 제한을 설정합니다. 최소값은 WMI가 이벤트 알림 속도를 늦추기 시작해야 하는 경우를 나타내고, 최대값은 이벤트 삭제를 시작할 시기를 나타냅니다. 낮은 임계값과 높은 임계값의 기본값은 10000000(10MB) 및 2000000(20MB)입니다. 또한 MaxWaitOnEvents 속성을 설정하여 WMI가 이벤트를 삭제하기 전에 대기해야 하는 시간을 설명할 수 있습니다. MaxWaitOnEvents 기본값은 2000 또는 2초입니다.
VBScript에서 비동기 이벤트 알림 수신
이벤트 알림을 수신하는 스크립팅 호출은 기본적으로 동일한 보안 문제가 있는 모든 비동기 호출과 동일합니다. 자세한 내용은 VBScript사용하여 비동기 호출 만들기를 참조하세요.
VBScript 비동기 이벤트 알림을 받으려면
WScript.CreateObject 호출하고 "WbemScripting"의 progid 및 SWbemSink개체 형식을 지정하여 싱크 개체를 만듭니다. 싱크 개체가 알림을 받습니다.
처리하려는 각 이벤트에 대한 서브루틴을 작성합니다. 다음 표에서는 SWbemSink 이벤트를 나열합니다.
이벤트 의미 OnObjectReady 개체의 반환 결과를 싱크로 보고합니다. 이 호출을 사용하면 작업이 완료될 때까지 매번 하나의 개체가 반환됩니다. OnCompleted 비동기 호출이 완료되면 보고합니다. 이 이벤트는 작업이 무기한인 경우 발생하지 않습니다. OnObjectPut 비동기 전송 작업의 완료를 보고합니다. 이 이벤트는 인스턴스 또는 저장된 클래스의 개체 경로를 반환합니다. OnProgress 진행 중인 비동기 호출의 상태를 보고합니다. 모든 공급자가 중간 진행률 보고서를 지원하는 것은 아닙니다. 취소 이 개체 싱크와 연결된 미해결 비동기 작업을 모두 취소합니다.
다음 VBScript 코드 예제에서는 10초 폴링 간격으로 프로세스 삭제를 알 수 있습니다. 이 스크립트에서 서브루틴 SINK_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)에서 이벤트를 모니터링하고 수신하기 위한 별도의 스레드만 만듭니다. 해당 스레드가 메시지를 받으면 스레드는 주 애플리케이션에 알깁니다.
별도의 스레드를 헌납하면 이벤트가 도착할 때까지 기다리는 동안 기본 프로세스가 다른 작업을 수행할 수 있습니다. 알림을 비동기식으로 전달하면 성능이 향상되지만 원하는 것보다 보안이 저하될 수 있습니다. C++에서는 IWbemUnsecuredApartment 인터페이스를 사용하거나 보안 설명자에 대한 액세스 검사를 수행할 수 있습니다. 자세한 내용은 비동기 호출보안 설정을 참조하세요.
비동기 이벤트 알림 설정하려면
비동기 알림을 초기화하기 전에 메모리 부족 방지 매개 변수가 Win32_WMISetting올바르게 설정되었는지 확인합니다.
수신할 이벤트의 종류를 결정합니다.
WMI는 내장 및 내재 이벤트를 지원합니다. 내장 이벤트는 WMI에서 미리 정의된 이벤트인 반면, 외래 이벤트는 타사 공급자가 정의한 이벤트입니다. 자세한 내용은 받을 이벤트 유형을 확인하세요.
다음 절차에서는 C++에서 비동기 이벤트 알림을 받는 방법을 설명합니다.
C++ 비동기 이벤트 알림을 받으려면
애플리케이션을 설정할 때 CoInitializeEx 및 CoInitializeSecurity 함수를 호출하십시오.
CoInitializeEx 호출하면 COM이 초기화되지만 CoInitializeSecurity WMI에 소비자 프로세스를 호출할 수 있는 권한이 부여됩니다. 또한 CoInitializeEx 함수를 사용하면 비동기 알림에 필요한 다중 스레드 애플리케이션을 프로그래밍할 수 있습니다. 자세한 내용은 WMI 보안 유지 관리를 참조하세요.
이 항목의 코드는 올바르게 컴파일하려면 다음 참조 및 #include 문이 필요합니다.
#define _WIN32_DCOM #include <iostream> using namespace std; #include <wbemidl.h>
다음 코드 예제에서는 CoInitializeEx 호출하고 CoInitializeSecurity임시 이벤트 소비자를 설정하는 방법을 설명합니다.
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; } // ... }
IWbemObjectSink 인터페이스를 통해 싱크 개체를 만듭니다.
WMI는 IWbemObjectSink 사용하여 이벤트 알림을 보내고 비동기 작업 또는 이벤트 알림에 대한 상태를 보고합니다.
IWbemServices::ExecNotificationQueryAsync 메서드에 대한 호출을 사용하여 이벤트 소비자를 등록합니다.
pResponseHandler 매개 변수가 이전 단계에서 만든 싱크 개체를 가리키는지 확인합니다.
등록의 목적은 필요한 알림만 수신하는 것입니다. 불필요한 알림을 받으면 처리 및 배달 시간이 낭비됩니다. WMI의 필터링 기능을 최대한 활용하지 않습니다.
그러나 임시 소비자는 둘 이상의 이벤트 유형을 받을 수 있습니다. 이 경우 임시 소비자는 각 이벤트 유형에 대해 IWbemServices::ExecNotificationQueryAsync 별도로 호출해야 합니다. 예를 들어 소비자는 새 프로세스를 만들 때(인스턴스 생성 이벤트 또는 __InstanceCreationEvent) 및 특정 레지스트리 키(RegistryKeyChangeEvent같은 레지스트리 이벤트)에 대한 변경 내용에 대한 알림을 요구할 수 있습니다. 따라서 소비자는 인스턴스 생성 이벤트를 등록하기 위해 ExecNotificationQueryAsync을 한 번 호출하고, 레지스트리 이벤트에 등록하기 위해 ExecNotificationQueryAsync를 또 한 번 호출합니다.
여러 이벤트에 등록하는 이벤트 소비자를 만들도록 선택하는 경우 동일한 싱크에 여러 클래스를 등록하지 않아야 합니다. 대신 등록된 이벤트의 각 클래스에 대해 별도의 싱크를 사용합니다. 전용 싱크를 사용하면 처리를 간소화하고 유지 관리를 지원하므로 다른 등록에 영향을 주지 않고 하나의 등록을 취소할 수 있습니다.
이벤트 소비자에서 필요한 모든 작업을 수행합니다.
이 단계에는 대부분의 코드가 포함되어야 하며 사용자 인터페이스에 이벤트를 표시하는 등의 활동이 포함되어야 합니다.
완료되면 IWbemServices::CancelAsyncCall 이벤트에 대한 호출을 사용하여 임시 이벤트 소비자의 등록을 취소합니다.
CancelAsyncCall 호출이 성공 또는 실패하는지 여부에 관계없이 개체 참조 수가 0에 도달할 때까지 싱크 개체를 삭제하지 마세요. 자세한 내용은 메서드호출을 참조하세요.