Как получить доступ к MTP-устройствам через командную строку в Windows?

Вопрос или проблема

Большинство устройств MTP (Media Transfer Protocol) отображаются в Проводнике Windows под своим именем или GUID, но у них не назначена буква диска.

Как я могу получить доступ к файлам на таких устройствах из командной строки? Используя либо cmd.exe, либо PowerShell.

К сожалению, API, предоставляемые MTP, очень отличаются от стандартных файловых систем. Поэтому невозможно представить устройство MTP как читаемую/записываемую файловую систему. Основная причина:

Wikipedia говорит:

Ни стандарты MTP, ни PTP не допускают прямого изменения объектов. Вместо этого измененные объекты должны быть загружены заново в полном объеме, что может занять много времени для крупных объектов. При использовании PTP/MTP размер файла должен быть известен на этапе открытия.

Ваша обычная программа копирования файлов просто открывает источник и целевой файл и копирует данные порциями из исходного файла в целевой. Это не сработает с MTP, так как вам нужно использовать специальные функции MTP, а стандартные примитивы файловой системы (чтение, перемотка, запись) недоступны.

Существуют также другие ограничения. Например, число файлов, которые могут быть прочитаны или записаны одновременно на устройстве MTP, сильно ограничено. Устройство просто не ведет себя как файловая система.

Я предполагаю, что только для чтения драйвер файловой системы для устройства MTP может быть возможен, но из-за вышеописанных проблем он будет мало полезен, поэтому никто не стал его создавать.

Существует проприетарная (но все же удобная) программа: MTP Drive (https://www.mtpdrive.com/), которая позволяет “подключать” устройства MTP как диски в Windows. С некоторыми разумными ограничениями она делает отличную работу!

Мне удалось подключить Garmin Descent Mk2i (для использования с SubSurface Dive Log) используя MTPMount (проект с открытым исходным кодом) Версия 9.18.0 на Windows 10.

Для этого необходимо установить Dokan (Dokany 1.5.1.1000), который предоставляет файловую систему FUSE для приложений Windows.

ЗАМЕТКА 1: В настоящее время последняя версия (19.8.0, ссылка выше) MTPMount не обновлена для работы с последней версией v2.x Dokan, вам нужно использовать версию Dokany 1.5.1.1000.

ЗАМЕТКА 2: MTPMount является приложением командной строки и не делает очевидным, что именно вам нужно ввести.
После нескольких минут неудачных попыток я нашел, что следующее сработало для меня.

.\mtpmount-x64.exe mount "Descent Mk2i" "Primary"

Вы можете попробовать составить что-то с MTPMon из набора для портирования MTP.

В качестве альтернативы, PowerShell может создавать COM объекты и вызывать их методы, так что возможно, что вы сможете использовать API, которые использует Проводник Windows (например, 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"
    }
}

И наконец, скопируйте элементы из достигнутого sourceFolder в пункт назначения:

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)

Ответ или решение

Доступ к устройствам MTP через командную строку в Windows

Введение

В современных операционных системах, таких как Windows, устройства, работающие по протоколу передачи медиафайлов (MTP), часто подключаются к компьютеру через USB. Несмотря на то что такие устройства появляются в проводнике Windows, они не имеют присвоенной буквы диска, что затрудняет доступ к их содержимому с помощью стандартных командных утилит. В данной статье мы рассмотрим различные способы доступа к MTP-устройствам с использованием командной строки в Windows и PowerShell.

Особенности MTP

Важно отметить, что MTP функционирует по другим принципам, чем традиционные файловые системы. MTP не позволяет напрямую изменять объекты на устройстве. Вместо этого, для модификации файла необходимо его полностью повторно загрузить, что может занять много времени для крупных объектов. Поэтому использование стандартных команд, таких как copy или xcopy, не будет работать.

Доступ через PowerShell

  1. Создание COM-объектов: PowerShell позволяет создавать объекты COM и вызывать их методы, что открывает доступ к API, используемым проводником Windows. Благодаря этому вы можете получить список доступных устройств MTP и работать с ними.

    Пример кода для доступа к MTP-устройству:

    $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
  2. Требуемые библиотеки: Для работы с MTP через PowerShell можно использовать проект GitHub под названием powershell-mtp-file-transfer. Этот проект содержит готовые скрипты для работы с MTP-устройствами.

  3. Переход к интересующей папке: После получения объекта устройства, вы можете перемещаться по его иерархии файловых папок.

    $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 "Не найден каталог $phoneFolderName"
       }
    }
  4. Копирование файлов: Ниже приведён пример функции, которая копирует файлы с устройства MTP на локальный диск:

    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 "Элемент '$itemName' уже существует"
       }
       else
       {
           Write-Host ("Копирование: {0}{1}" -f $fullSourceDirPath, $item.Name)
           $destDirShell.CopyHere($item)
       }
    }

Использование сторонних утилит

Существует несколько сторонних инструментов, которые могут упростить доступ к MTP-устройствам:

  1. MTP Drive: Программное обеспечение, которое позволяет "монтировать" MTP-устройства как диски в Windows. Оно имеет ограниченные возможности, но является хорошим решением для обычных пользователей. Вы можете скачать его с официального сайта MTP Drive.

  2. MTPMount: Это программа с открытым исходным кодом, которая также позволяет монтировать MTP-устройства. Для её работы требуется предварительная установка Dokan, что предоставляет интерфейс FUSE для приложений Windows.

    Пример команды для монтирования устройства:

    .\mtpmount-x64.exe mount "Descent Mk2i" "Primary"

Заключение

Доступ к MTP-устройствам через командную строку в Windows представляет собой определённую сложность из-за особенностей работы этого протокола. Путем использования PowerShell и сторонних утилит, таких как MTP Drive или MTPMount, вы сможете управлять файлами на MTP-устройствах, обходя ограничения стандартных методов. Важно следить за обновлениями используемых инструментов, чтобы использовать последние возможности и исправления программного обеспечения.

Оцените материал
Добавить комментарий

Капча загружается...