서비스 열기Opening a Service

응용 프로그램에서 서비스에 대 한 작업을 수행 하려면 (예: 콘텐츠 열거 또는 지원 되는 이벤트 또는 메서드 설명 검색) 서비스를 열어야 합니다.Before your application can perform operations on a service, for example, enumerating content or retrieving descriptions of supported events or methods, it must open the service. Wst서비스 Apis광대 응용 프로그램에서이 작업은 다음 표에 설명 된 인터페이스를 사용 하 여 ServiceEnumeration .cpp 모듈에 설명 되어 있습니다.In the WpdServicesApiSample application, this task is demonstrated in the ServiceEnumeration.cpp module using the interfaces described in the following table.

인터페이스Interface DescriptionDescription
IPortableDeviceServiceManagerIPortableDeviceServiceManager 장치에서 서비스를 열거 하는 데 사용 됩니다.Used to enumerate the services on a device.
IPortableDeviceServiceIPortableDeviceService 장치 서비스에 대 한 연결을 여는 데 사용 됩니다.Used to open a connection to a device service.
IPortableDeviceValuesIPortableDeviceValues 응용 프로그램의 클라이언트 정보를 저장 하는 데 사용 됩니다.Used to hold the application's client information.

서비스를 여는 메서드는 IPortableDeviceService:: Open입니다.The method that opens a service is IPortableDeviceService::Open. 이 메서드는 서비스에 대 한 PnP (플러그 앤 플레이) 식별자와 응용 프로그램의 클라이언트 정보를 포함 하는 Iportabledevicevalues 개체 라는 두 개의 인수를 사용 합니다.This method takes two arguments: a Plug-and-Play (PnP) identifier for the service and an IPortableDeviceValues object that contains the application's client information.

지정 된 서비스에 대 한 PnP 식별자를 얻기 위해 응용 프로그램은 IPortableDeviceServiceManager:: GetDeviceServices 메서드를 호출 합니다.To obtain a PnP identifier for a given service, your application calls the IPortableDeviceServiceManager::GetDeviceServices method. 이 메서드는 서비스 범주 GUID (예: 서비스 연락처)의 서비스에 대 한 PnP 식별자 배열을 검색 합니다.This method retrieves an array of PnP identifiers for services of a service category GUID (for example SERVICE Contacts).

샘플 서비스 응용 프로그램은 ServiceEnumeration .cpp 모듈의 EnumerateContactsServices 메서드 내에서 연락처 서비스의 PnP 식별자를 검색 합니다.The sample Service application retrieves a PnP identifier for Contacts services within the EnumerateContactsServices method in the ServiceEnumeration.cpp module. 다음 코드 샘플은이 메서드에서 가져온 것입니다.The following code sample is taken from this method.

// For each device found, find the contacts service
for (dwIndex = 0; dwIndex < cPnpDeviceIDs; dwIndex++)
{
    DWORD   cPnpServiceIDs = 0;
    PWSTR   pPnpServiceID  = NULL;

    // First, pass NULL as the PWSTR array pointer to get the total number
    // of contacts services (SERVICE_Contacts) found on the device.
    // To find the total number of all services on the device, use GUID_DEVINTERFACE_WPD_SERVICE.
    hr = pServiceManager->GetDeviceServices(pPnpDeviceIDs[dwIndex], SERVICE_Contacts, NULL, &cPnpServiceIDs);
    
    if (SUCCEEDED(hr) && (cPnpServiceIDs > 0))
    {                               
        // For simplicity, we are only using the first contacts service on each device
        cPnpServiceIDs = 1;
        hr = pServiceManager->GetDeviceServices(pPnpDeviceIDs[dwIndex], SERVICE_Contacts, &pPnpServiceID, &cPnpServiceIDs);

        if (SUCCEEDED(hr))
        {
            // We've found the service, display it and save its PnP Identifier
            ContactsServicePnpIDs.Add(pPnpServiceID);

            printf("[%d] ", static_cast<DWORD>(ContactsServicePnpIDs.GetCount()-1));

            // Display information about the device that contains this service.
            DisplayDeviceInformation(pServiceManager, pPnpServiceID);

            // ContactsServicePnpIDs now owns the memory for this string
            pPnpServiceID = NULL;
        }
        else
        {
            printf("! Failed to get the first contacts service from '%ws, hr = 0x%lx\n",pPnpDeviceIDs[dwIndex],hr);
        }
    }
}

응용 프로그램이 서비스에 대 한 PnP 식별자를 검색 한 후 클라이언트 정보를 설정 하 고 IPortableDeviceService:: Open을 호출할 수 있습니다.After your application retrieves the PnP identifier for the service, it can set up the client information and call IPortableDeviceService::Open.

샘플 응용 프로그램에서이 메서드는 ServiceEnumeration .cpp 모듈의 ChooseDeviceService 내에서 호출 됩니다.In the sample application, this method is called within ChooseDeviceService in the ServiceEnumeration.cpp module.

IPortableDeviceService 는 두 가지 CoCreateInstance 용 clsid를 지원 합니다.IPortableDeviceService supports two CLSIDs for CoCreateInstance. CLSID _ PortableDeviceService 는 자유 스레드된 마샬러를 집계 하지 않는 IPortableDeviceService 포인터를 반환 합니다. CLSID _ PortableDeviceServiceFTM 는 자유 스레드된 마샬러를 집계 하는 IPortableDeviceService 포인터를 반환 하는 새 CLSID입니다.CLSID_PortableDeviceService returns an IPortableDeviceService pointer that does not aggregate the free-threaded marshaler; CLSID_PortableDeviceServiceFTM is a new CLSID that returns an IPortableDeviceService pointer that aggregates the free-threaded marshaler. 두 포인터는 모두 동일한 기능을 지원 합니다.Both pointers support the same functionality otherwise.

단일 스레드 아파트에 상주 하는 응용 프로그램은 인터페이스 포인터 마샬링에 대 한 오버 헤드를 제거 하므로 CLSID _ PortableDeviceServiceFTM 를 사용 해야 합니다.Applications that live in Single Threaded Apartments should use CLSID_PortableDeviceServiceFTM as this eliminates the overhead of interface pointer marshaling. CLSID _ PortableDeviceService 은 레거시 응용 프로그램에서 계속 지원 됩니다.CLSID_PortableDeviceService is still supported for legacy applications.

hr = CoCreateInstance(CLSID_PortableDeviceServiceFTM,
                      NULL,
                      CLSCTX_INPROC_SERVER,
                      IID_PPV_ARGS(&pService));
if (SUCCEEDED(hr))
{
    hr = pService->Open(ContactsServicesArray[uiCurrentService], pClientInformation);
    if (FAILED(hr))
    {
        if (hr == E_ACCESSDENIED)
        {
            printf("Failed to Open the service for Read Write access, will open it for Read-only access instead\n");

            pClientInformation->SetUnsignedIntegerValue(WPD_CLIENT_DESIRED_ACCESS, GENERIC_READ);

            hr = pService->Open(ContactsServicesArray[uiCurrentService], pClientInformation);

            if (FAILED(hr))
            {
                printf("! Failed to Open the service for Read access, hr = 0x%lx\n",hr);
            }
        }
        else
        {
            printf("! Failed to Open the service, hr = 0x%lx\n",hr);
        }
    }

IPortableDeviceService 인터페이스IPortableDeviceService Interface

IPortableDeviceValues 인터페이스IPortableDeviceValues Interface

IPortableDeviceServiceManager 인터페이스IPortableDeviceServiceManager Interface

WpdServicesApiSampleWpdServicesApiSample