移动设备已成为生活中不可或缺的一部分,人们利用手机、平板电脑等移动设备管理、传输、浏览文件已经变得司空见惯。然而,在Windows应用中如何实现设备文件管理,使得用户可以方便地在PC端和移动端之间进行文件传输和管理?这就需要了解PortableDeviceAPI。
一、什么是PortableDeviceAPI?
PortableDeviceAPI是Windows的一个API,用于访问可携带设备,例如MP3、照相机、移动设备等。使用PortableDeviceAPI可以方便地实现在Windows应用程序中管理和控制可移动设备,例如传输文件或控制设备的状态。
二、如何使用PortableDeviceAPI连接设备?
1.添加PortableDeviceAPI
在程序中添加PortableDeviceAPI需要的库文件PortableDeviceTypes.dll和PortableDeviceApi.dll。这两个文件通常被放置在“Windows Kits\10\Redist\ucrt\DLLs\x64”目录下。
2.搜索设备
准备好PortableDeviceAPI后,就可以使用它来搜索连接到计算机上的设备。使用IPortableDeviceManager中的GetDevices方法可以获取连接到计算机上的设备的列表。
```cpp
hr = CoCreateInstance(CLSID_PortableDeviceManager,
NULL,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&pPortableDeviceManager));
if (FAILED(hr))
{
wprintf(L"Failed to create an instance of the IPortableDeviceManager interface. Error code: %u.\n", hr);
return hr;
}
// Get the device collection
hr = pPortableDeviceManager->GetDevices(NULL, &dwDeviceCount);
if (FAILED(hr))
{
wprintf(L"Failed to get device collection from the IPortableDeviceManager interface. Error code: %u.\n", hr);
CoUninitialize();
return hr;
}
if(dwDeviceCount == 0)
{
wprintf(L"No devices are connected.\n");
CoUninitialize();
return S_OK;
}
// Enumerate the connected portable devices
hr = pPortableDeviceManager->GetDevices(pPnPDeviceIDs, &dwDeviceCount);
if (FAILED(hr))
{
wprintf(L"Failed to enumerate devices on the IPortableDeviceManager interface. Error code: %u.\n", hr);
CoUninitialize();
return hr;
}
```
成功获取设备列表后,可以遍历列表并手动选择要连接的设备。
3.连接设备
选择要连接的设备后,需要通过设备ID连接到设备。使用IPortableDeviceServiceManager接口中的GetDeviceService方法来获取设备服务并连接并打开会话。
```cpp
hr = CoCreateInstance(CLSID_PortableDeviceServiceManager,
NULL,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&pServiceManager));
if (FAILED(hr))
{
wprintf(L"Failed to create an instance of the IPortableDeviceServiceManager interface. Error code: %u.\n", hr);
CoUninitialize();
return hr;
}
hr = pServiceManager->GetDeviceService(pPnPDeviceIDs[0], &pDeviceService);
if (FAILED(hr))
{
wprintf(L"Failed to get service from the IPortableDeviceServiceManager interface. Error code: %u.\n", hr);
pPortableDeviceManager->Release();
CoUninitialize();
return hr;
}
hr = pDeviceService->Open(&pClientInfo, &pPortableDeviceValues);
if (FAILED(hr))
{
wprintf(L"Failed to open a session to the portable device %ws. Error code: %u.\n", pszPnPDeviceID, hr);
pPortableDeviceManager->Release();
CoUninitialize();
return hr;
}
```
4.断开连接
关闭会话并从设备服务中断开会话。
```cpp
hr = pDeviceService->Close();
if (FAILED(hr))
{
wprintf(L"Failed to close the device session with %ws. Error code: %u.\n", pszPnPDeviceID, hr);
}
pDeviceService->Release();
pServiceManager->Release();
```
三、如何在Windows应用程序中管理易携式设备?
成功连接到设备后,就可以使用PortableDeviceAPI在Windows应用程序中管理易携式设备。
1.获取设备属性
使用IPortableDeviceContent接口可以获取设备属性,并使用PortableDeviceValues类从PortableDeviceAPI库中检索属性。
```cpp
hr = pDeviceContent->Properties(&pProperties);
if (FAILED(hr))
{
wprintf(L"Failed to get properties from the IPortableDeviceContent interface. Error code: %u.\n", hr);
return hr;
}
hr = pProperties->GetValues(WPD_DEVICE_CAPABILITIES, NULL, &pCapabilities);
if (FAILED(hr))
{
wprintf(L"Failed to get the WPD_DEVICE_CAPABILITIES value. Error code: %u.\n", hr);
return hr;
}
// Retrieve the values from the property collection
hr = pCapabilities->GetCount(&dwValues);
for (ULONG i = 0; i < dwValues; i++)
{
PROPERTYKEY Key = { 0 };
PROPVARIANT Value = { 0 };
hr = pCapabilities->GetAt(i, &Key, &Value);
if (SUCCEEDED(hr))
{
if (IsEqualPropertyKey(Key, WPD_FUNCTIONAL_OBJECT_CATEGORY))
{
if (Value.vt == VT_CLSID)
{
CLSID cls = *(Value.puuid);
}
}
}
PropVariantClear(&Value);
}
```
2.获取设备中的Object
在易携式设备中,设备可以包含多个对象,例如照片、音乐或其他文件。可以使用IPortableDeviceContent接口遍历设备以检索设备中的对象。
```cpp
// Enumerate the contents of the camera roll
hr = pDeviceContent->EnumObjects(WPD_DEVICE_OBJECT_ID, NULL, NULL, &pObjectIDs);
if (FAILED(hr))
{
wprintf(L"Failed to enumerate objects on the IPortableDeviceContent interface. Error code: %u.\n", hr);
return hr;
}
hr = pObjectIDs->GetCount(&cObjects);
if (FAILED(hr))
{
wprintf(L"Failed to get the count of objects being returned from the IPortableDeviceContent interface. Error code: %u.\n", hr);
return hr;
}
for (ULONG i = 0; i < cObjects; i++)
{
LPWSTR szObjectID = NULL;
hr = pObjectIDs->GetAt(i, &szObjectID);
// Create an IPortableDeviceProperties instance to retrieve the properties of an object.
hr = CoCreateInstance(CLSID_PortableDeviceProperties,
NULL,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&pObjectProperties));
if (FAILED(hr))
{
wprintf(L"Failed to create an instance of the IPortableDeviceProperties interface. Error code: %u.\n", hr);
return hr;
}
hr = pObjectProperties->GetSupportedProperties(szObjectID, &pKeys);
hr = pObjectProperties->GetValues(szObjectID, pKeys, &pValues);
PropVariantClear(&Value);
}
```
3.传输文件
使用IPortableDeviceResources接口可以传输文件,使用IPortableDeviceResourceManager发布和管理存储在设备上的资源。
```cpp
hr = CoCreateInstance(CLSID_PortableDeviceResources,
NULL,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&pPortableDeviceResources));
hr = pPortableDeviceResources->GetSupportedResources(pszObjectID, &pResources);
DWORD dwResourceCount = 0;
hr = pResources->GetCount(&dwResourceCount);
for (DWORD dwIndex = 0; dwIndex < dwResourceCount; dwIndex++)
{
PWSTR pszResourceKey = NULL;
hr = pResources->GetAt(dwIndex, &pszResourceKey);
if (SUCCEEDED(hr))
{
IStream* pStream = NULL;
hr = pPortableDeviceResources->GetStream(pszObjectID, pszResourceKey, STGM_READ, &dwOptimalTransferSize, &pStream);
if (SUCCEEDED(hr))
{
// Transfer the data from the stream to the file
}
}
}
```
四、总结
PortableDeviceAPI是Windows的一个API,用于访问可携带设备,例如MP3、照相机、移动设备等。使用PortableDeviceAPI可以方便地实现在Windows应用程序中管理和控制可携带设备,例如传输文件或控制设备的状态。在使用PortableDeviceAPI时,需要添加PortableDeviceAPI需要的库文件,并使用IPortableDeviceManager中的GetDevices方法搜索设备。接着,使用IPortableDeviceServiceManager中的GetDeviceService方法连接设备并打开会话。连接到设备后,就可以使用IPortableDeviceContent接口获取设备属性,并使用PortableDeviceValues类从PortableDeviceAPI库中检索属性。使用IPortableDeviceContent接口还可以遍历设备以检索设备中的对象。最后,使用IPortableDeviceResources接口可以传输文件。