我必须使用哪个 Win32 功能将文件复制到智能手机文件夹?

Posted

技术标签:

【中文标题】我必须使用哪个 Win32 功能将文件复制到智能手机文件夹?【英文标题】:Which Win32 function must I use to copy a file to a smartphone folder? 【发布时间】:2017-07-25 04:35:49 【问题描述】:

使用 WindowsForms 技术,我正在尝试将本地存储在硬盘驱动器 (C:\) 上的文件复制到存储在通过 USB 连接的智能手机设备上的文件夹中。

文件夹“路径”在资源管理器导航栏中使用友好名称表示为 MyPCName\MyName\Card\android,在 Windows 内部则表示为 ::20D04FE0-3AEA-1069-A2D8-08002B30309D\\\?\usb#vid_04e8&pid_6860&ms_comp_mtp&samsung_android#6&612ff8b&1&0000#6ac27878-a6fa-4155-ba85-f98f491d4f33\SID-20002,SECZ9519043CHOHB01,31426543616\01A00139-011B-0124-3301-29011C013501

我通过使用 COM Shell.BrowseForFolder 方法获得了那个“内部路径”,然后检查了返回对象的 FolderItem.Path 属性。

然后在获得路径后,我尝试了 CopyFileCopyFileEx Win32 函数来复制文件,但它们不起作用。他们似乎无法识别目录路径。

我使用的语法是这样的:

Dim dirPath As String = "::20D04FE0-3AEA-1069-A2D8-08002B30309D\\\?\usb#vid_04e8&pid_6860&ms_comp_mtp&samsung_android#6&612ff8b&1&0000#6ac27878-a6fa-4155-ba85-f98f491d4f33\SID-20002,SECZ9519043CHOHB01,31426543616\01A00139-011B-0124-3301-29011C013501"
NativeMethods.CopyFile("C:\MyFile.ext", dirPath & "\MyFile.ext", failIfExists:=True)

在该代码中,CopyFile() 函数返回 FalseMarshal.GetLastWin32Error() 函数返回 0x3 Win32 错误代码。

我使用的 CopyFile/CopyFileEx 定义与 Pinvoke.net 网站上发布的定义相同(C# 版本):

http://www.pinvoke.net/default.aspx/kernel32/CopyFile.html http://www.pinvoke.net/default.aspx/kernel32.copyfileex

如果用户只需将文件从资源管理器实例拖动到智能手机目录即可复制文件,那么我认为很明显,只需查找和使用与 Windows 自身执行该类型相同的 Win32 函数,就可以通过编程方式复制该文件从 UI 端进行复制操作。那我做错了什么?为什么 CopyFile/CopyFileEx 不能复制文件?我该如何复制它?

请注意,我正在寻找用 C# 或 VB.NET 编写的解决方案,该解决方案可以仅使用托管代码或使用非托管代码 P/Invoking Win32 函数来解决,但使用 Shell COM 等 COM 库除外对象(提供CopyHere() 方法)。我想学习并了解如何使用 Win32 API 成员进行这种文件复制操作。

【问题讨论】:

当你在资源管理器中打开sd卡文件夹shift-right click一个文件并点击复制为路径,你在剪贴板中得到什么样的路径? @GSerg CopyAsPath shell 扩展似乎不适用于此类设备,或者至少对于此特定设备,上下文菜单中的“复制为路径”选项未显示为它显示为普通(硬盘驱动器)文件夹。感谢您的评论 嗯,你也可以试试Procmon。将过滤器设置为资源管理器进程,看看它调用了什么以及使用了哪些参数。 CopyFile/CopyFileEx 仅适用于实际文件和目录,即,一个真实的文件系统,对内核可见,因为它安装在本地或作为网络驱动器。您正在处理一个 Shell 文件夹,它是一个仅存在于 Shell 命名空间内的虚拟对象。内核对此一无所知。 Shell COM 对象是处理此问题的正确方法,我不确定您为什么要避免使用它们。我猜你可以尝试 SHFileOperation 但这已被弃用。 【参考方案1】:

您正在寻找 Windows 便携式设备 API。

https://msdn.microsoft.com/en-us/library/windows/desktop/dd388998(v=vs.85).aspx

编辑:我已成功使用此 API,使用 C# 中的 COM 互操作,在我的 Android Galaxy S3 上读取/写入文件。

您还可以在以下博客中找到有关在 C# 中使用此 API 的详细信息:https://github.com/geersch/WPD

【讨论】:

感谢您的建议。我已经在我的 .NET 项目中引用了相关的 WPD COM 库,但实际上我不知道如何列出设备、选择所需的设备并最终将文件复制到其文件夹之一。此外,MSDN 示例仅适用于 C++ msdn.microsoft.com/en-us/library/windows/desktop/…,而 CodePlex 或 GirHub 等站点中的 C# 中的现有示例是非常大的通用项目,涵盖了传输文件的更多内容,或者换句话说:对于没有经验的用户来说是一个痛苦的分析在 WPD 中。无论如何,我正在检查它以尝试理解.. 我不认为这个建议是正确的。操作系统应该(并且能够)在复制文件时将设备 API 抽象出来。 请解释这个建议是如何“不正确”或“差”的。您要么提供 WPD-API 的替代方案,要么将这种非建设性的批评留给自己。我们的研究得出结论,实际上没有其他方法可以做到这一点,只能使用上面提到的(非常笨重的)API。有强烈的迹象表明,在使用此类设备时,即使是操作系统或资源管理器也在使用此 API。

以上是关于我必须使用哪个 Win32 功能将文件复制到智能手机文件夹?的主要内容,如果未能解决你的问题,请参考以下文章

怎样把win7系统下的word文件复制到ubuntu的文件中

如何使用 Win32 句柄在 C++ 中获取文件名? [复制]

如何将 Win32 合并到 SDL 项目中?

怎么将dll的文件复制替换到C:\windows\system32 win7

win10远程桌面无法复制粘贴

5♥☆基于STM32的智能手环√★☆