随着移动设备的普及,像智能手机、平板电脑、MP3/MP4等便携式设备已经成为人们日常必不可少的物品。对于这些便携式设备的数据管理、文件传输等操作,常常需要使用传统的数据线或者各种广告充斥的第三方软件。但是,我们不知道的是,Windows 系统中自带了一个功能强大的 API,可以轻松管理便携式设备——PortableDeviceApi。
PortableDeviceApi 是由 Microsoft 公司推出的一个通用的 API,可以管理大部分连接在 Windows 系统上的便携式设备。其主要功能包括:获取设备列表、创建文件夹、上传/下载文件、删除文件等。通过 PortableDeviceApi,我们可以在 Windows 系统中直接管理便携式设备,而无需使用其它软件等。本次,我们简单介绍如何使用 PortableDeviceApi 实现便携设备的管理、文件传输等操作,以及 PortableDeviceApi 的常见问题解决方法。
第一步:创建 PortableDevice 对象
PortableDeviceApi 通过 PortableDevice 对象实现与便携式设备的交互,因此使用 PortableDeviceApi 的第一步便是创建 PortableDevice 对象。
PortableDevice p_device;
p_device.Open("DEVICE_ID");
其中,DEVICE_ID 是便携式设备的唯一标识符,可以通过函数 EnumerateDevices() 获取。如果该便携式设备未连接或者设备 ID 错误,则会抛出异常。
第二步:获取便携式设备信息
创建 PortableDevice 对象以后,可以通过它获取该便携式设备的信息。PortableDevice 对象的成员函数主要包括:
- GetObjectIDs():获取该设备中对象的 ID,
- GetProperty():获取设备的属性值,
- SetProperty():设置设备的属性值。
以获取设备名称为例:
PortableDeviceKeyCollection p_keys;
p_keys.Add(WPD_DEVICE_FRIENDLY_NAME);
PortableDeviceValues p_values;
p_device.GetValues(WPD_DEVICE_OBJECT_ID, NULL, p_keys, &p_values);
std::wstring p_device_name;
PROPERTYKEY p_key_device_name = PKEY_Device_FriendlyName;
p_values.GetStringValue(p_key_device_name, &p_device_name);
第三步:创建文件夹
PortableDeviceApi 通过 IStorage 制作文件夹,可以使用该接口实现便携式设备中的创建、删除等操作。
IStorage *p_root;
p_device.Content().CreateObjectWithPropertiesAndData(
L"新建文件夹",
NULL,
&fmtid_GenericFolder,
NULL,
STGM_READWRITE | STGM_SHARE_EXCLUSIVE,
&p_root,
NULL);
p_root->Release();
第四步:文件上传
PortableDeviceApi 使用 IStream 实现文件的上传,使用该接口时,需要指定文件名、格式、大小等。
IStream *p_stream;
PortableDeviceApi::CreateStream(p_device, L"test.jpg", 32768, &p_stream);
for (auto iter = buffer.cbegin(); iter != buffer.cend();)
{
ULONG cbWritten;
p_stream->Write(&*iter, buffer.size() - buffer_pos, &cbWritten);
iter += cbWritten;
}
p_stream->Release();
第五步:文件下载
PortableDeviceApi 使用 IStream 接口实现文件下载,首先需要使用 GetObjectIDs() 获取需要下载的文件的 ID,然后使用该 ID 和 IStream 接口中的 OpenStream() 函数,打开该文件对应的流。
PortableDeviceContent p_content;
p_device.Content(&p_content);
PortableDeviceApi::GetObjectIDs(p_content, &p_obj_ids);
p_content.Properties()->GetStringValue(WPD_OBJECT_PARENT_ID, &p_parent_id);
for (ULONG i = 0; i < p_obj_ids.size(); ++i)
{
TCHAR p_file_name[MAX_PATH] = {};
DWORD cb_name = MAX_PATH;
PortableDeviceApi::GetFileName(p_device, p_obj_ids[i], p_file_name, &cb_name);
if (lstrcmpi(p_file_name, "test.jpg") == 0)
{
HRESULT hr = p_content.Transfer()->OpenStream(p_obj_ids[i], STGM_READ, &p_stream, NULL, NULL);
if (FAILED(hr)) continue;
hr = PortableDeviceApi::DownloadStream(p_stream);
if (FAILED(hr)) continue;
p_stream->Release();
break;
}
}
第六步:删除文件夹
PortableDeviceApi 同样使用 IStorage 接口实现文件夹的删除,使用 RemoveItem() 函数实现文件夹的删除。
PortableDeviceContent p_content;
p_device->Content(&p_content);
IStorage* p_storage;
p_content->Properties()->GetStringValue(WPD_OBJECT_PARENT_ID, &p_parent_id);
p_content->Properties()->GetStringValue(WPD_OBJECT_ID, &p_obj_id);
p_content->Transfer()->Delete(p_obj_id, NULL);
至此,我们初步了解了如何使用 PortableDeviceApi 实现便携式设备的管理、文件传输等操作。在使用过程中,常常会遇到一些错误,我们也需要掌握常见的解决方法。例如,操作 Windows Phone 设备的时候,在开发阶段需要设置特殊的权限,否则程序将没有操作权限;同时,在进行文件的上传下载时,需要注意流的关闭,否则会在下一次使用流的时候出现问题。
总之, PortableDeviceApi 是 Windows 平台的一个非常实用的接口,能够大大简化便携式设备的管理,使得操作变得更加方便和便捷。如果您经常需要对移动设备进行管理、传输等操作, PortableDeviceApi 无疑是您值得学习的一项技术。