다음을 통해 공유


C++를 사용하여 비동기 호출 만들기

C++로 작성된 WMI 애플리케이션은 IWbemServices COM 인터페이스의 여러 메서드를 사용하여 비동기 호출을 수행할 수 있습니다. 그러나 WMI 메서드 또는 공급자 메서드 호출하는 데 권장되는 절차는 비동기 호출보다 반동기 호출이 더 안전하기 때문에 반동기 호출을 사용하는 것입니다. 자세한 내용은 C++로 반동기 호출 만들기비동기 호출 보안 설정를 참조하세요.

다음 절차에서는 프로세스에서 싱크를 사용하여 비동기 호출을 만드는 방법을 설명합니다.

C++ 사용하여 비동기 호출을 하려면

  1. IWbemObjectSink 인터페이스를 구현합니다.

    비동기 호출을 하는 모든 애플리케이션은 IWbemObjectSink구현해야 합니다. 또한 임시 이벤트 소비자는 IWbemObjectSink 구현하여 이벤트 알림을 받습니다.

  2. 대상 WMI 네임스페이스에 로그온합니다.

    애플리케이션은 초기화 단계에서 항상 coInitializeSecurityCOM 함수를 호출해야 합니다. 비동기 호출을 하기 전에 그렇게 하지 않으면 WMI는 비동기 호출을 완료하지 않고 애플리케이션 싱크를 해제합니다. 자세한 내용은 WMI 애플리케이션대한 COM 초기화를 참조하세요.

  3. 싱크에 대한 보안을 설정합니다.

    비동기 호출은 애플리케이션에 대한 WMI 액세스를 허용하는 등 처리해야 할 수 있는 다양한 보안 문제를 만듭니다. 자세한 내용은 비동기 호출보안 설정을 참조하세요.

  4. 비동기 호출을 합니다.

    이 메서드는 WBEM_S_NO_ERROR 성공 코드와 함께 즉시 반환됩니다. 애플리케이션은 작업이 완료 될 때까지 기다리는 동안 다른 작업을 진행할 수 있습니다. WMI는 애플리케이션의 IWbemObjectSink 구현에서 메서드를 호출하여 애플리케이션에 다시 보고합니다.

  5. 필요한 경우 구현의 업데이트를 정기적으로 확인합니다.

    애플리케이션은 WBEM_FLAG_SEND_STATUS대한 비동기 호출에서 lFlags 매개 변수를 설정하여 중간 상태 알림을 받을 수 있습니다. WMI는 호출 상태를 IWbemObjectSinklFlags 매개 변수를 WBEM_STATUS_PROGRESS로 설정하여 보고합니다.

  6. 필요한 경우 IWbemServices::CancelCallAsync 메서드를 호출하여 WMI가 처리를 완료하기 전에 호출을 취소할 수 있습니다.

    CancelAsyncCall 메서드는 IWbemObjectSink 인터페이스에 대한 포인터를 즉시 해제하여 비동기 처리를 취소하고 CancelAsyncCall 반환하기 전에 포인터가 해제되도록 보장합니다.

    IUnsecured 인터페이스를 구현하는 래퍼 개체를 사용하여 IWbemObjectSink호스트하는 경우 몇 가지 추가 복잡성이 발생할 수 있습니다. 애플리케이션은 원래 비동기 호출에서 전달된 CancelAsyncCall 동일한 포인터를 전달해야 하므로 취소가 필요하지 않다는 것이 분명해질 때까지 애플리케이션이 래퍼 개체를 유지해야 합니다. 자세한 내용은 비동기 호출보안 설정을 참조하세요.

  7. 완료되면 포인터를 정리하고 애플리케이션을 종료합니다.

    WMI는 SetStatus 메서드를 통해 최종 상태 호출을 제공합니다.

    메모

    최종 상태 업데이트를 보낸 후 WMI는 IWbemObjectSink 인터페이스를 구현하는 클래스에 대한 Release 메서드를 호출하여 개체 싱크를 해제합니다. 이전 예제에서는 QuerySink::Release 메서드입니다. 싱크 개체의 수명을 제어하려는 경우 초기 참조 수가 1인 싱크를 구현할 수 있습니다.

     

    클라이언트 애플리케이션이 서로 다른 두 개의 겹치는 비동기 호출에서 동일한 싱크 인터페이스를 전달하는 경우 WMI는 콜백 순서를 보장하지 않습니다. 겹치는 비동기 호출을 만드는 클라이언트 애플리케이션은 다른 싱크 개체를 전달하거나 호출을 직렬화해야 합니다.

다음 예제에는 다음 참조 및 #include 문이 필요합니다.

#include <iostream>
using namespace std;
#pragma comment(lib, "wbemuuid.lib")
#include <wbemidl.h>

다음 예제에서는 ExecQueryAsync 메서드를 사용하여 비동기 쿼리를 만드는 방법을 설명하지만 보안 설정을 만들거나 IWbemObjectSink 개체를 해제하지는 않습니다. 자세한 내용은 비동기 호출보안 설정을 참조하세요.

// Set input parameters to ExecQueryAsync.
BSTR QueryLang = SysAllocString(L"WQL");
BSTR Query = SysAllocString(L"SELECT * FROM MyClass");

// Create IWbemObjectSink object and set pointer.
QuerySink *pSink = new QuerySink;

IWbemServices* pSvc = 0;

// Call ExecQueryAsync.
HRESULT hRes = pSvc->ExecQueryAsync(QueryLang, 
                                    Query, 
                                    0, 
                                    NULL, 
                                    pSink);

// Check for errors.
if (hRes)
{
    printf("ExecQueryAsync failed with = 0x%X\n", hRes);
    SysFreeString(QueryLang);
    SysFreeString(Query);
    delete pSink;    
    return ERROR;
}

메모

위의 코드는 QuerySink 클래스가 정의되지 않았기 때문에 오류 없이 컴파일되지 않습니다. QuerySink대한 자세한 내용은 IWbemObjectSink참조하세요.

 

메서드 호출