随着科技的不断发展,人们越来越离不开电子设备,特别是智能手机、平板电脑等便携式设备。然而,这些设备与计算机交互使用时,面临各种问题,例如数据传输、音乐视频同步、设备管理等等。为解决这些问题,微软提供了PortableDeviceAPI接口,方便开发人员进行设备管理和数据交互。
一、PortableDeviceAPI简介
PortableDeviceAPI是微软Windows操作系统中的一个应用程序编程接口,它是为便携式设备和计算机之间的数据传输和管理而设计的。该接口提供了许多常见操作,如读写文件、拷贝和删除文件、列出设备中已有的文件等。通过使用这些接口,应用程序开发人员可以轻松地与设备进行通信,管理设备上的文件和数据,以及同步内容。
PortableDeviceAPI接口是Microsoft Windows的一部分,因此无需进行额外的安装。另外还有一些基于PortableDeviceAPI的应用程序,如Windows Media Player、Windows Live Photo Gallery、Windows Media Center等等,这些应用程序可以帮助用户管理与设备交互的数据。
二、PortableDeviceAPI的使用示例
1. 获取设备列表
PortableDeviceManager类提供了一个静态方法GetDevices(),该方法返回一个PortableDeviceCollection对象,该对象包含计算机中连接的所有便携式设备。
```C++
PortableDeviceManager manager = new PortableDeviceManager();
PortableDeviceCollection devices = new PortableDeviceCollection();
manager.GetDevices(devices);
```
2. 连接设备
连接设备需要生成一个PortableDevice对象,PortableDevice对象提供了连接设备所需的一切信息。
```C++
PortableDevice device = new PortableDevice();
device.Open(deviceId, _clientInfo);
```
其中,deviceId指的是要连接的设备的唯一标识符。_clientInfo是一个IPortableDeviceValues对象,它提供了关于连接设备的其他有用信息,例如设备驱动器名称、广告周期、设备名称等等。
3. 读取设备信息
读取设备信息需要使用PortableDevice类的方法Content(),该方法返回IPortableDeviceContent对象,它提供了一种简便的访问设备特定数据的方法。例如:
```C++
IPortableDeviceContent content;
device.Content(out content);
IPortableDeviceProperties properties;
content.Properties(out properties);
IPortableDeviceValues deviceValues;
properties.GetValues(WPD_DEVICE_OBJECT_PROPERTIES_V1, null, out deviceValues);
```
4. 读取设备文件
通过PortableDevice类的Content()方法,可以访问设备文件。例如:
```C++
PortableDeviceFile file = new PortableDeviceFile();
IPortableDeviceContent content;
device.Content(out content);
IPortableDeviceFolder rootFolder;
content.GetRootObjects(out rootFolder);
IPortableDeviceProperties properties;
rootFolder.Properties(out properties);
IPortableDeviceProperties resources;
properties.GetValues(WPD_OBJECT_RESOURCES_ALL, null, out resources);
PortableDeviceApiLib._tagpropertykey contentType = new PortableDeviceApiLib._tagpropertykey();
string contentTypeValue;
resources.GetAt(0, ref contentType, out contentTypeValue);
PortableDeviceApiLib.IStream wpdStream = null;
PortableDeviceApiLib.IStream wpdInputStream = null;
PortableDeviceApiLib.IStream wpdOutputStream = null;
var pObj = new PortableDeviceApiLib._tagpropertykey();
properties.GetAt(0, ref pObj, out var pv);
IPortableDeviceKeyCollection keys = GetRequiredPropertiesForContentType(contentTypeValue);
rootFolder.GetFiles(keys, out PortableDeviceApiLib.IEnumPortableDeviceObjectIDs objectIds);
uint fetched = 0;
do
{
objectIds.Next(1, objectIdsBuffer, ref fetched);
if (fetched > 0)
{
PortableDeviceApiLib.IPortableDeviceProperties propertiesForSpecificItem;
PortableDeviceApiLib.IPortableDeviceResources resourcesForSpecificItem;
foreach (var objectId in objectIdsBuffer)
{
content.Properties(out propertiesForSpecificItem);
propertiesForSpecificItem.GetValues(objectId, keys, out PortableDeviceApiLib.IPortableDeviceValues values);
string name = System.IO.Path.GetFileName(objectId);
var prop = new PortableDeviceApiLib._tagpropertykey();
values.GetAt(0, ref prop, out var pv2);
bool tryMap = TryGetContent(partnerToClientResourceMap, contentTypeValue, prop);
object[] propertiesByType = valuesValuesMapper.GetValuesContentById(contentTypeValue, values, tryMap);
resources.GetStream(objectId, ref contentType, 0, ref wpdInputStream);
FileStream writeStream = new FileStream($"C:\\{Guid.NewGuid()}_{name}", FileMode.Create);
wpdStream = new PortableDeviceApiLib.StreamWrapper(wpdInputStream, writeStream);
PortableDeviceApiLib.PortableDeviceHelper.CopyStream(wpdStream, writeStream);
writeStream.Close();
wpdStream = null;
}
}
} while (fetched > 0);
```
5. 写入设备文件
写入设备文件需要使用PortableDevice类中的Content()方法和IPortableDeviceValues对象。例如:
```C++
PortableDeviceApiLib._tagpropertykey keyContentType = new PortableDeviceApiLib._tagpropertykey();
string contentType = "image/jpeg";
PortableDeviceApiLib.IStream wpdStream2 = null;
PortableDeviceApiLib.PortableDeviceValues values = new PortableDeviceApiLib.PortableDeviceValues();
values.SetStringValue(new PortableDeviceApiLib._tagpropertykey() { fmtid = PortableDeviceApiLib.WPD_OBJECT_FORMAT_JPEG.guid, pid = 2 }, "test name.jpg");
values.SetUnsignedLargeIntegerValue(new PortableDeviceApiLib._tagpropertykey() { fmtid = PortableDeviceApiLib.WPD_OBJECT_FORMAT_JPEG.guid, pid = 31 }, 1024*1024);
values.SetStringValue(new PortableDeviceApiLib._tagpropertykey() { fmtid = PortableDeviceApiLib.WPD_OBJECT_FORMAT_JPEG.guid, pid = 3210 }, contentType);
PortableDeviceApiLib.IStream iStream = null;
FSTools.BREAK_IF_FILE_NOT_EXISTS(FileToWrite);
using (iStream = new PortableDeviceApiLib.StreamWrapper(new FileStream(FileToWrite, FileMode.Open, FileAccess.ReadWrite), null))
{
wpdStream2 = iStream.Clone();
IPortableDeviceContent content2 = null;
PortableDevice.PortableDeviceClass contentUtil = new PortableDevice.PortableDeviceClass();
IPortableDeviceValues values2 = null;
contentUtil.Open(device.Id, content2);
content2.Transfer(out IPortableDeviceResources ppResources);
ppResources.CreateObjectWithPropertiesAndData(values, out string ppObjectID, wpdStream2, null);
}
```
三、Conclusion
PortableDeviceAPI接口提供了一种方便的方式,使应用程序能够读取和管理便携式设备的数据。例如,计算机上的音乐播放器可以从便携式设备中读取音乐文件,拷贝到计算机上进行播放。同样,应用程序也可以将音乐文件写回到便携式设备,以在其他设备上播放。
PortableDeviceAPI的使用并不复杂,开发人员只需熟悉其API,即可轻松开发应用,管理与设备交互的数据。这种便利性对于便携设备用户来说也是最大的福利。