Bagikan melalui


Membuka Layanan

Sebelum aplikasi Anda dapat melakukan operasi pada layanan, misalnya, menghitung konten atau mengambil deskripsi peristiwa atau metode yang didukung, aplikasi harus membuka layanan. Dalam aplikasi WpdServicesApiSample, tugas ini ditunjukkan dalam modul ServiceEnumeration.cpp menggunakan antarmuka yang dijelaskan dalam tabel berikut.

Antarmuka Deskripsi
IPortableDeviceServiceManager Digunakan untuk menghitung layanan pada perangkat.
IPortableDeviceService Digunakan untuk membuka koneksi ke layanan perangkat.
IPortableDeviceValues Digunakan untuk menyimpan informasi klien aplikasi.

 

Metode yang membuka layanan adalah IPortableDeviceService::Open. Metode ini mengambil dua argumen: pengidentifikasi Plug-and-Play (PnP) untuk layanan dan objek IPortableDeviceValues yang berisi informasi klien aplikasi.

Untuk mendapatkan pengidentifikasi PnP untuk layanan tertentu, aplikasi Anda memanggil metode IPortableDeviceServiceManager::GetDeviceServices . Metode ini mengambil array pengidentifikasi PnP untuk layanan GUID kategori layanan (misalnya Kontak LAYANAN).

Aplikasi Layanan sampel mengambil pengidentifikasi PnP untuk layanan Kontak dalam metode EnumerateContactsServices dalam modul ServiceEnumeration.cpp. Sampel kode berikut diambil dari metode ini.

// 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);
        }
    }
}

Setelah aplikasi Anda mengambil pengidentifikasi PnP untuk layanan, aplikasi dapat menyiapkan informasi klien dan memanggil IPortableDeviceService::Open.

Dalam aplikasi sampel, metode ini dipanggil dalam ChooseDeviceService dalam modul ServiceEnumeration.cpp.

IPortableDeviceService mendukung dua CLSID untuk CoCreateInstance. CLSID_PortableDeviceService mengembalikan penunjuk IPortableDeviceService yang tidak mengagregasi marshaler berulir bebas; CLSID_PortableDeviceServiceFTM adalah CLSID baru yang mengembalikan penunjuk IPortableDeviceService yang menggabungkan marshaler berulir bebas. Kedua pointer mendukung fungsionalitas yang sama.

Aplikasi yang tinggal di Single Threaded Apartments harus menggunakan CLSID_PortableDeviceServiceFTM karena ini menghilangkan overhead marshaling pointer antarmuka. CLSID_PortableDeviceService masih didukung untuk aplikasi warisan.

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);
        }
    }

Antarmuka IPortableDeviceService

Antarmuka IPortableDeviceValues

Antarmuka IPortableDeviceServiceManager

WpdServicesApiSample