共用方式為


開啟服務

您的應用程式必須先開啟服務,才能對服務執行作業,例如列舉內容或擷取支援事件或方法的描述。 在 WpdServicesApiSample 應用程式中,此工作會使用下表所述的介面,在 ServiceEnumeration.cpp 模組中示範。

介面 描述
IPortableDeviceServiceManager 用來列舉裝置上的服務。
IPortableDeviceService 用來開啟裝置服務的連線。
IPortableDeviceValues 用來保存應用程式的用戶端資訊。

 

開啟服務的方法為 IPortableDeviceService::Open。 這個方法採用兩個引數:服務的隨插即用 (PnP) 識別碼,以及包含應用程式用戶端資訊的 IPortableDeviceValues 物件。

若要取得指定服務的 PnP 識別碼,您的應用程式會呼叫 IPortableDeviceServiceManager::GetDeviceServices 方法。 這個方法會擷取服務類別 GUID 服務的 PnP 識別碼陣列 (,例如 SERVICE 連絡人) 。

範例服務應用程式會擷取 ServiceEnumeration.cpp 模組中 EnumerateContactsServices 方法內的 Contacts 服務的 PnP 識別碼。 下列程式碼範例取自這個方法。

// 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

在範例應用程式中,此方法會在 ServiceEnumeration.cpp 模組的 ChooseDeviceService 內呼叫。

IPortableDeviceService 支援兩個適用于 CoCreateInstance的 CLSID。 CLSID_PortableDeviceService 會傳回不會匯總自由執行緒封送處理器的 IPortableDeviceService 指標; CLSID_PortableDeviceServiceFTM 是新的 CLSID,會傳回 IPortableDeviceService 指標,以匯總自由執行緒封送處理器。 這兩個指標都支援相同的功能,否則為 。

位於單一線程 Apartment 中的應用程式應該使用 CLSID_PortableDeviceServiceFTM ,因為這樣可消除介面指標封送處理的額外負荷。 版應用程式仍支援CLSID_PortableDeviceService。

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 介面

IPortableDeviceValues 介面

IPortableDeviceServiceManager 介面

WpdServicesApiSample