Как получить доступ к MTP-устройствам из командной строки в Windows?
Большинство устройств MTP ( Media Transfer Protocol) отображаются в проводнике Windows под своим именем устройства или идентификатором GUID, но им не назначается буква диска.
Как я могу получить доступ к файлам на таких устройствах из командной строки? Использование cmd.exe или PowerShell.
5 ответов
К сожалению, API, предоставляемые MTP, сильно отличаются от API-интерфейсов обычной файловой системы. Поэтому показ устройства MTP как файловой системы для чтения / записи невозможен. Главная причина:
Википедия говорит:
Ни стандарты MTP, ни стандарты PTP не допускают непосредственного изменения объектов. Вместо этого модифицированные объекты должны быть повторно загружены целиком, что может занять много времени для больших объектов. При использовании PTP/MTP размер файла должен быть известен на начальном этапе.
Ваша обычная программа копирования файлов просто открывает исходный и целевой файл и копирует данные в виде фрагментов из исходного файла в целевой. Это не будет работать с MTP, так как вам нужно использовать специальные функции MTP, а общие примитивы файловой системы (чтение, поиск, запись) недоступны.
Есть и другие ограничения. Например, количество файлов, которые могут быть прочитаны или записаны одновременно на устройстве MTP, строго ограничено. Устройство просто не ведет себя как файловая система.
Я полагаю, что драйвер файловой системы только для чтения для устройства MTP может быть возможен, но из-за проблем, описанных выше, он будет очень мало полезен, поэтому никто не удосужился его создать.
Существует проприетарная (но все же приятная) программа: MTP Drive ( http://www.mtpdrive.com/index.html), которая позволяет вам "монтировать" устройства MTP как диски в Windows. С некоторыми разумными ограничениями это делает большую работу!
Мне удалось установить Garmin Descent Mk2i (для использования с журналом погружений SubSurface ) с помощью MTPMount (проект с открытым исходным кодом) версии 9.18.0 в Windows 10.
Это зависит от установки Dokan (Dokany 1.5.1.1000), который предоставляет файловую систему FUSE приложениям Windows.
ПРИМЕЧАНИЕ 1. В настоящее время последняя версия (19.8.0, ссылка выше) MTPMount не обновлена для работы с последней версией Dokan v2.x, вам необходимо использовать версию Dokany 1.5.1.1000.
ПРИМЕЧАНИЕ 2. MTPMount — это приложение командной строки, поэтому не понятно, что вам нужно вводить.
После нескольких минут неудачных попыток я обнаружил, что мне помогло следующее.
.\mtpmount-x64.exe mount "Descent Mk2i" "Primary"
Возможно, вам удастся что-то сделать вместе с MTPMon набора для переноса MTP.
В качестве альтернативы PowerShell может создавать COM- объекты и вызывать их методы, поэтому вы можете использовать API-интерфейсы, которые использует Windows Explorer (например, GetDeviceInfo() и GetObjectInfo()).
Если это правда, что телефоны Android используют MTP для подключения к компьютеру в режиме «Передача файлов», то 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\testfileonpc.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)