WPD API - 无法从设备传输内容(包括SSCCE)

时间:2017-02-27 19:05:34

标签: c++ windows qt mtp wpd

我需要枚举MTP安卓设备的内容,并将文件从设备传输到Windows PC。

按照此处的指南Transferring Content from a Device to a PC,我尝试将简单文本文档传输到指定目录。但是,输出文件始终为空,即使返回的值指出$tester = $array['EfxReport']['USDecisionPowerExpressReports']['USDecisionPowerExpressReport']['USConsumerCreditReport']['USFICO']['FICOScore'];

我仅使用推荐的Windows API调用创建了一个SSCCE,以轻松重现该问题。我使用了API文档和official sample project作为参考。

main.cpp

Qt project file

为了测试,我有一个通过MTP与一个名为X number of bytes have been written.的根目录上的文件夹连接的Android手机,里面有一个文件testFolder,文本为testfile.txt。运行此应用程序时,输出表明已写入11个字节,但文件为空。请自己尝试一下?

我似乎无法理解文件为何总是空的。有什么想法吗?

感谢您的时间。

1 个答案:

答案 0 :(得分:2)

  hr = SHCreateStreamOnFile(strOriginalFileName, STGM_CREATE|STGM_WRITE, &finalFileStream);

通常有助于识别常见的编码模式。无论何时创建文件,都必须始终关闭该文件。在C语言中你有fopen(),你必须调用fclose()。在winapi中你有CreateFile(),你必须调用CloseHandle()。即使在很多资源管理都是自动化的运行时环境中,比如.NET,当你创建FileStream时,你必须调用Close()或使用 using 语句。

代码无法明确关闭finalFileStream

这有后果,你找到了一个。在没有内存泄漏的情况下,SHCreateStreamOnFile的实现不知道何时将任何缓冲但尚未写入的数据刷新到该文件。所以你最终得到一个没有内容的文件。

任何接口指针(如IStream)的合约都是您必须显式调用其Release()函数。请注意,代码忘记了为所有它使用的接口指针一致地执行此操作。不是唯一的问题,当你调用CoInitialize / Ex()然后你必须调用CoUninitialize()。只需使用黄金法则,你就必须在这样的代码中明确清理。

修正:

  hr = StreamCopy(finalFileStream, ...);
  if (FAILED(hr)) saysomething(hr);          // Forgotten in original code
  finalFileStream->Release();                // Now it is good.

您可以在C ++中使用智能指针类型,如CComPtr<>,以便自动完成。