大多数 MTP (媒体传输协议) 设备会以其设备名称或 GUID 显示在 Windows 文件资源管理器中,但并未分配驱动器号。
如何从命令行访问此类设备上的文件?使用 cmd.exe 或 PowerShell。
答案1
不幸的是,MTP 公开的 API 与普通文件系统 API 非常不同。因此,将 MTP 设备公开为读/写文件系统无法使用。主要原因:
维基百科说:
MTP 和 PTP 标准都不允许直接修改对象。相反,必须重新上传修改后的对象,这对于大型对象来说可能需要很长时间。使用 PTP/MTP 时,必须在开始阶段知道文件大小。
您的常用文件复制程序只会打开源文件和目标文件,然后将数据分块从源文件复制到目标文件。这不适用于 MTP,因为您需要使用 MTP 特殊函数,并且通用文件系统原语(读取、查找、写入)不可用。
还有其他限制。例如,MTP 设备上可同时读取或写入的文件数量受到严重限制。该设备的行为根本就不像文件系统。
我想只读用于 MTP 设备的文件系统驱动程序可能是可行的,但由于上述问题,它用处不大,所以没人愿意去创建它。
答案2
有一个专有的(但仍然很好)程序:MTP Drive(https://www.mtpdrive.com/) 允许您在 Windows 中将 MTP 设备“安装”为驱动器。虽然存在一些合理的限制,但它确实做得很好!
答案3
我已经成功安装了一个Garmin Descent Mk2i(与使用水下潜水日志) 使用 MTP 接口(一个开源项目)版本 9.18.0在 Windows 10 上。
这依赖于安装 Dokan(Dokany 1.5.1.1000),它公开了一个保险丝文件系统到 Windows 应用程序。
注 1:目前,MTPMount 的最新版本(19.8.0,如上链接)尚未更新,无法与最新的 v2.x Dokan 配合使用,您需要使用1.5.1.1000 Dokany 版本
注 2:MTPMount 是一个命令行应用程序,不会明确显示您需要输入的内容。
经过几分钟的失败尝试后,我发现下面的方法对我有用。
.\mtpmount-x64.exe mount "Descent Mk2i" "Primary"
答案4
如果 Android 手机在“文件传输”模式下确实使用 MTP 连接到 PC,那么 PowerShell 就是一个解决方案,我刚刚在 StackOverflow 上回答了这个问题:https://stackoverflow.com/a/75543733/3090890
下面是我在 StackOverflow 上回答的稍微编辑过的副本。
我找到了这个 PowerShell 脚本:https://github.com/nosalan/powershell-mtp-file-transfer/ 免责声明:我不是该脚本的作者,因此版权归他所有!为了回答这个问题,我从链接源中复制并粘贴了代码片段,以便提供一些解释。
访问手机的技巧如下:通过 USB 连接时,手机应处于“文件传输”模式:
$phoneName = "Nokia 7.2"
$o = New-Object -com Shell.Application
$rootComputerDirectory = $o.NameSpace(0x11)
$phoneDirectory = $rootComputerDirectory.Items() | Where-Object {$_.Name -eq $phoneName} | select -First 1
然后你就可以遍历到你想要的目录:
$sourceFolder = $phoneDirectory
$phoneFolderName = "Internal shared storage\DCIM\Camera"
foreach($pathSegment in ($phoneFolderName -split "\\"))
{
$sourceFolder = $sourceFolder.GetFolder.Items() | Where-Object {$_.Name -eq $pathSegment} | select -First 1
if($sourceFolder -eq $null)
{
throw "Not found $phoneFolderName folder"
}
}
最后将项目从到达的源文件夹复制到目标文件夹:
function Get-FullPathOfMtpDir($mtpDir)
{
$fullDirPath = ""
$directory = $mtpDir.GetFolder
while($directory -ne $null)
{
$fullDirPath = -join($directory.Title, '\', $fullDirPath)
$directory = $directory.ParentFolder;
}
return $fullDirPath
}
$targetFolder = "E:\Test"
$destDirShell = (new-object -com Shell.Application).NameSpace($targetFolder)
$fullSourceDirPath = Get-FullPathOfMtpDir $sourceFolder
foreach ($item in $sourceFolder.GetFolder.Items())
{
$itemName = ($item.Name)
$fullFilePath = Join-Path -Path $targetFolder -ChildPath $itemName
if(Test-Path $fullFilePath)
{
Write-Host "Element '$itemName' already exists"
}
else
{
$copiedCount++;
Write-Host ("Copying #{0}: {1}{2}" -f $copiedCount, $fullSourceDirPath, $item.Name)
$destDirShell.CopyHere($item)
}
}
Write-Host "Copied '$copiedCount' elements from '$fullSourceDirPath'"
也可以将文件复制回手机。这里我以交换目标和源为例,将“E:\Test\atestfileonpc.txt”复制到手机的“DCIM\Camera”文件夹中:
$sourceDirShell = (new-object -com Shell.Application).NameSpace($targetFolder)
$targetDirShell = $sourceFolder
$item = $sourceDirShell.Items() | Where-Object {$_.Name -eq "atestfileonpc.txt"} | select -First 1
targetDirShell.GetFolder.CopyHere($item)