打开服务
应用程序必须先打开服务,然后才能对服务执行操作(例如枚举内容或检索支持的事件或方法的说明)。 在 WpdServicesApiSample 应用程序中,此任务使用下表中所述的接口在 ServiceEnumeration.cpp 模块中演示。
接口 | 说明 |
---|---|
IPortableDeviceServiceManager | 用于枚举设备上的服务。 |
IPortableDeviceService | 用于打开与设备服务的连接。 |
IPortableDeviceValues | 用于保存应用程序的客户端信息。 |
打开服务的方法为 IPortableDeviceService::Open。 此方法采用两个参数:即插即用 (PnP) 标识符的服务,以及包含应用程序的客户端信息的 IPortableDeviceValues 对象。
若要获取给定服务的 PnP 标识符,应用程序会调用 IPortableDeviceServiceManager::GetDeviceServices 方法。 此方法检索服务类别 GUID (例如服务联系人) 的服务的 PnP 标识符数组。
示例服务应用程序在 ServiceEnumeration.cpp 模块的 EnumerateContactsServices 方法中检索联系人服务的 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 指针。 否则,这两个指针都支持相同的功能。
位于单线程单元中的应用程序应使用 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);
}
}
相关主题