|
发表于 2025-4-2 01:55:47
|
显示全部楼层
江西省九江市
ai回答如下
在C++中,可以通过Windows便携式设备(WPD)API将文件上传到MTP设备的某个路径。以下是基于WPD API实现文件上传的步骤和示例代码:
步骤
1. 初始化设备和会话:连接并枚举目标MTP设备,建立会话句柄。
2. 获取目标文件夹对象:通过设备的文件系统结构找到目标文件夹。
3. 创建文件对象:在目标文件夹中创建一个新文件对象。
4. 写入数据:将文件内容写入到新创建的文件对象中。
5. 关闭文件和清理资源:完成文件写入后,关闭文件对象并释放所有资源。
示例代码
以下是一个C++示例代码,展示如何将文件上传到MTP设备的指定路径:
```cpp
#include <windows.h>
#include <PortableDevice.h>
#include <PortableDeviceTypes.h>
#include <PortableDeviceApi.h>
#include <iostream>
#include <fstream>
#pragma comment(lib, "PortableDeviceGUIDs.lib")
// 打开MTP设备
HRESULT OpenMTPDevice(IPortableDevice** ppDevice, LPWSTR pwszPnpDeviceID)
{
IPortableDeviceManager* pDeviceManager = nullptr;
HRESULT hr = CoCreateInstance(__uuidof(PortableDeviceManager), nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDeviceManager));
if (FAILED(hr)) return hr;
hr = pDeviceManager->GetDeviceIDs(1, &pwszPnpDeviceID);
if (FAILED(hr)) return hr;
hr = CoCreateInstance(__uuidof(PortableDevice), nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(ppDevice));
if (FAILED(hr)) return hr;
hr = (*ppDevice)->Open(pwszPnpDeviceID, PORTABLE_DEVICE_ACCESS_READWRITE);
pDeviceManager->Release();
return hr;
}
// 获取目标文件夹的ID
HRESULT GetFolderID(IPortableDevice* pDevice, LPCWSTR wszPath, PROPVARIANT* pFolderID)
{
IPortableDeviceContent* pContent = nullptr;
HRESULT hr = pDevice->Content(IID_PPV_ARGS(&pContent));
if (FAILED(hr)) return hr;
IPortableDeviceContent* pFolderContent = pContent;
std::wstring path = wszPath;
while (path.find(L"\\") != std::wstring::npos)
{
std::wstring folderName = path.substr(0, path.find(L"\\"));
path = path.substr(path.find(L"\\") + 1);
IPortableDeviceValues* pValues = nullptr;
hr = pFolderContent->GetMetadata(folderName.c_str(), &pValues);
if (FAILED(hr))
{
pFolderContent->Release();
return hr;
}
PROPVARIANT pvFolderID;
PropVariantInit(&pvFolderID);
hr = pValues->GetValue(WPD_OBJECT_ID, &pvFolderID);
pValues->Release();
if (FAILED(hr))
{
pFolderContent->Release();
return hr;
}
IPortableDeviceContent* pParentContent = pFolderContent;
hr = pParentContent->GetContent(pvFolderID, IID_PPV_ARGS(&pFolderContent));
pParentContent->Release();
PropVariantClear(&pvFolderID);
if (FAILED(hr)) return hr;
}
hr = pFolderContent->GetMetadata(path.c_str(), &pContent);
if (FAILED(hr))
{
pFolderContent->Release();
return hr;
}
hr = pContent->GetValue(WPD_OBJECT_ID, pFolderID);
pFolderContent->Release();
return hr;
}
// 上传文件到MTP设备
HRESULT UploadFileToMTPDevice(IPortableDevice* pDevice, LPCWSTR wszFolderPath, LPCWSTR wszFileName, LPCWSTR wszFilePath)
{
PROPVARIANT pvFolderID;
PropVariantInit(&pvFolderID);
HRESULT hr = GetFolderID(pDevice, wszFolderPath, &pvFolderID);
if (FAILED(hr)) return hr;
IPortableDeviceContent* pContent = nullptr;
hr = pDevice->Content(IID_PPV_ARGS(&pContent));
if (FAILED(hr)) return hr;
IPortableDeviceResources* pResources = nullptr;
hr = pContent->Resources(IID_PPV_ARGS(&pResources));
if (FAILED(hr)) return hr;
std::ifstream file(wszFilePath, std::ios::binary);
if (!file)
{
std::cerr << "Failed to open file." << std::endl;
return E_FAIL;
}
std::vector<BYTE> buffer(std::istreambuf_iterator<char>(file), {});
file.close();
IPortableDeviceValues* pValues = nullptr;
hr = CoCreateInstance(__uuidof(PortableDeviceValues), nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pValues));
if (FAILED(hr)) return hr;
pValues->SetStringValue(WPD_OBJECT_NAME, wszFileName);
pValues->SetGuidValue(WPD_OBJECT_FORMAT, WPD_FILE_FORMAT_UNKNOWN);
pValues->SetUnsignedLargeIntegerValue(WPD_OBJECT_SIZE, buffer.size());
pValues->SetGuidValue(WPD_OBJECT_PARENT_ID, pvFolderID);
IPortableDeviceContent* pParentContent = nullptr;
hr = pContent->CreateObjectWithPropertiesAndData(pValues, &pParentContent, nullptr, nullptr);
if (FAILED(hr)) return hr;
IPortableDeviceStream* pStream = nullptr;
hr = pParentContent->GetStream(WPD_OBJECT_ID, &pStream);
if (FAILED(hr)) return hr;
hr = pStream->Write(buffer.data(), buffer.size(), nullptr);
pStream->Release();
pParentContent->Release();
pValues->Release();
pResources->Release();
pContent->Release();
PropVariantClear(&pvFolderID);
return hr;
}
int main()
{
CoInitializeEx(nullptr, COINIT_MULTITHREADED);
IPortableDevice* pDevice = nullptr;
LPWSTR pwszPnpDeviceID = nullptr;
HRESULT hr = OpenMTPDevice(&pDevice, pwszPnpDeviceID);
if (FAILED(hr))
{
std::cerr << "Failed to open MTP device." << std::endl;
CoUninitialize();
return -1;
}
LPCWSTR wszFolderPath = L"内部存储设备\\aa\\bb"; // 目标文件夹路径
LPCWSTR wszFileName = L"example.txt"; // 目标文件名
LPCWSTR wszFilePath = L"C:\\path\\to\\example.txt"; // 本地文件路径
hr = UploadFileToMTPDevice(pDevice, wszFolderPath, wszFileName, wszFilePath);
if (FAILED(hr))
{
std::cerr << "Failed to upload file to MTP device." << std::endl;
}
else
{
std::cout << "File uploaded successfully." << std::endl;
}
pDevice->Release();
CoTaskMemFree(pwszPnpDeviceID);
CoUninitialize();
return 0;
}
```
代码说明
1. 设备连接和会话建立:通过`OpenMTPDevice`函数连接到MTP设备。
2. 获取目标文件夹ID:通过`GetFolderID`函数递归查找目标文件夹的ID。
3. 上传文件:通过`UploadFileToMTPDevice`函数将本地文件上传到目标文件夹。
4. 资源管理:在操作完成后,释放所有资源以避免内存泄漏。
注意事项
• 确保设备已正确连接并识别为MTP设备。
• 目标路径和文件名需要根据实际情况调整。
• 代码中未包含完整的错误处理逻辑,实际使用时需要进一步完善。
|
|