Apertura di un servizio
Prima che l'applicazione possa eseguire operazioni su un servizio, ad esempio enumerando il contenuto o recuperando descrizioni di eventi o metodi supportati, deve aprire il servizio. Nell'applicazione WpdServicesApiSample questa attività viene illustrata nel modulo ServiceEnumeration.cpp usando le interfacce descritte nella tabella seguente.
Interfaccia | Descrizione |
---|---|
IPortableDeviceServiceManager | Usato per enumerare i servizi in un dispositivo. |
IPortableDeviceService | Consente di aprire una connessione a un servizio del dispositivo. |
IPortableDeviceValues | Usato per contenere le informazioni client dell'applicazione. |
Il metodo che apre un servizio è IPortableDeviceService::Open. Questo metodo accetta due argomenti: un identificatore Plug-and-Play (PnP) per il servizio e un oggetto IPortableDeviceValues che contiene le informazioni client dell'applicazione.
Per ottenere un identificatore PnP per un determinato servizio, l'applicazione chiama il metodo IPortableDeviceServiceManager::GetDeviceServices . Questo metodo recupera una matrice di identificatori PnP per i servizi di un GUID di categoria di servizio,ad esempio CONTATTI SERVIZIO.
L'applicazione del servizio di esempio recupera un identificatore PnP per i servizi Contatti all'interno del metodo EnumerateContactsServices nel modulo ServiceEnumeration.cpp. L'esempio di codice seguente è tratto da questo metodo.
// 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);
}
}
}
Dopo che l'applicazione recupera l'identificatore PnP per il servizio, può configurare le informazioni client e chiamare IPortableDeviceService::Open.
Nell'applicazione di esempio questo metodo viene chiamato all'interno di ChooseDeviceService nel modulo ServiceEnumeration.cpp.
IPortableDeviceService supporta due CLSID per CoCreateInstance. CLSID_PortableDeviceService restituisce un puntatore IPortableDeviceService che non aggrega il marshalling a thread libero; CLSID_PortableDeviceServiceFTM è un nuovo CLSID che restituisce un puntatore IPortableDeviceService che aggrega il gestore di marshalling a thread libero. Entrambi i puntatori supportano la stessa funzionalità in caso contrario.
Le applicazioni che risiedono in apartment a thread singolo devono usare CLSID_PortableDeviceServiceFTM in quanto ciò elimina il sovraccarico del marshalling del puntatore di interfaccia. CLSID_PortableDeviceService è ancora supportato per le applicazioni legacy.
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);
}
}
Argomenti correlati