開啟服務
您的應用程式必須先開啟服務,才能對服務執行作業,例如列舉內容或擷取支援事件或方法的描述。 在 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);
}
}
相關主題