从PowerShell使用System.IO访问MTP存储

Jos*_* B. 5 powershell android mtp

我正在尝试访问MTP设备存储以自动执行文件复制,备份等操作。如果Windows资源管理器能够打开和浏览Android设备的内部存储和已连接的SD卡,如何使用PowerShell访问这些存储?

我发现了很多提示,例如“获取设备ID并使用WMI”

Windows资源管理器用于打开和浏览特别是Android存储的方式是什么?

是否可以使用类似此处的某些System.IO类?

$drives = [System.IO.DriveInfo]::GetDrives()
$r = $drives | Where-Object { $_.DriveType -eq 'Removable' -and $_.IsReady }
if ($r) {
    return @($r)[-1]
}
Run Code Online (Sandbox Code Playgroud)

我可以通过以下方式访问和浏览本地MTP(android)设备的内容:

$WIAdialog = New-Object -ComObject “WIA.CommonDialog”
$Device = $WIAdialog.ShowSelectDevice()
$Device = $WIAdialog.ShowAcquireImage()
$Device = $WIAdialog.ShowAcquisitionWizard()
$Device = $WIAdialog.ShowDeviceProperties()
$Device = $WIAdialog.ShowItemProperties()
$Device = $WIAdialog.ShowPhotoPrintingWizard()
$Device = $WIAdialog.ShowSelectItems()
$Device = $WIAdialog.ShowTransfer()
Run Code Online (Sandbox Code Playgroud)

但是此代码正在加载有关已存储图片的信息,即使在本地计算机上,该信息也太慢。是否可以避免加载有关图片的信息以加快加载和访问远程连接设备的速度?

在此先感谢您提供任何信息和提示!

小智 6

Function fn_PhoneFolder {
    Param($PhoneName, $PhoneFolder)

    Write-Host "Searching....$($PhoneName)" -ForegroundColor Green

    $Shell = new-object -com Shell.Application
    $ShellItem = $Shell.NameSpace(17).self #17 = My Computer (https://learn.microsoft.com/en-gb/windows/win32/api/shldisp/ne-shldisp-shellspecialfolderconstants?redirectedfrom=MSDN)
    $Phone = $ShellItem.GetFolder.items() | where { $_.name -eq $PhoneName }

    $FolderParts = @( $PhoneFolder.Split([system.io.path]::DirectorySeparatorChar) )

    $PhonePath = $Phone
        ForEach ($Part in $FolderParts) {
            If ($Part) {
                $PhonePath = $PhonePath.GetFolder.items() | where { $_.Name -eq $Part }
                }
            }

    $ReturnFiles = New-Object System.Collections.Generic.List[System.Object]

    $Files =  @($PhonePath.GetFolder.items())

    $Files

    ForEach ($File in $Files) {
        $TempFiles = @{}
        $TempFiles.Name = $File.Name
        $TempFiles.Path = $File.Path
        $TempFilesObject = New-Object PSobject -Property $TempFiles
        $ReturnFiles.Add($TempFilesObject)
        }

    Return $ReturnFiles

}

$MyPhoneFiles = fn_PhoneFolder -PhoneName "X19" -PhoneFolder "Internal shared storage\WhatsApp\Media\WhatsApp Images\Sent"
Run Code Online (Sandbox Code Playgroud)

更改最后一行的 PhoneName 和 PhoneFolder 以匹配“我的电脑”中显示的您的电话名称。此函数将拉回所选文件夹中所有文件的数组。感谢https://blog.daiyanyingyu.uk/2018/03/20/powershell-mtp/提供了通过 shell 文件夹搜索来查找手机的想法。


Joh*_*noo 5

这是我对 Stack Overflow (Stack Exchange) 的第一个回答,请考虑。

我正在处理同样的问题 - 我希望能够像在资源管理器中一样在 PowerShell 中使用 android 内部存储。我唯一的建议是我们可以安装 FTP 服务器(我最喜欢的是FTP 服务器)并按这种方式排序。到目前为止,我在超级用户上找到了这些答案:
打开命令提示符以访问 USB 连接的 Android 手机的文件夹
13 票并已接受

为了给可移动设备分配驱动器号,该设备必须支持 UMS(USB 大容量存储)协议。不幸的是,大多数较新的 Android 手机,尤其是那些没有可移动 SD 卡的手机,不支持 UMS。相反,它们支持 MTP(媒体传输协议)和 PTP(图片传输协议)协议。在此类设备中,无法将存储映射为 Windows 中的驱动器。

查看有关此 Superuser.com问题的更多详细信息:如何在 Windows 的命令行上访问 MTP 设备?

24 票并被接受

不幸的是,MTP 公开的 API 与普通文件系统 API 非常不同。因此,将 MTP 设备公开为读/写文件系统是不可能的。主要原因:

维基百科说:

MTP 和 PTP 标准都不允许直接修改对象。相反,修改后的对象必须全部重新上传,这对于大型对象可能需要很长时间。使用 PTP/MTP,必须在打开阶段就知道文件大小。

您的通用文件复制程序只是打开一个源文件和一个目标文件,然后将数据从源文件分块复制到目标文件。这不适用于 MTP,因为您需要使用 MTP 特殊功能,并且通用文件系统原语(读取、查找、写入)不可用。

还有其他限制。例如,可以在 MTP 设备上同时读取或写入的文件数量受到严重限制。该设备的行为不像文件系统。

我认为 MTP 设备的只读文件系统驱动程序可能是可能的,但由于上述问题,它几乎没有用,所以没有人费心去创建它。

2012 年 5 月 12 日 6:33 彼得·莫滕森 8,075 编辑

2012 年 1 月 10 日 20:08 haimg 15.9k 回答

只读文件系统驱动程序现在似乎存在:ptpdrive.com – Arne de Bruijn 2013 年 9 月 12 日 12:25

ptpdrive.com

实际上,这并非“不可能”。当您考虑到我在 Linux 上将 gphotofs 和 mtpfs 作为完全读/写的 FUSE 文件系统时 - 在 Windows 下完全有可能将其作为“驱动器号”来实现……他们只是没有提供它或容易。– Svartalf 2014 年 5 月 9 日,19:57

话虽如此,在某些选定的三星和索尼 Android 设备上,可以仅为外部存储(SD 卡)启用 UMS 模式。请参阅此应用程序 SG USB Mass Storage Enabler

此外,如果您的目标是通过命令提示符简单地将文件复制到 Android 设备或从 Android 设备复制文件,ADB 将允许您这样做。此实用程序是 Android SDK 工具的一部分。您将需要为您的安卓手机安装 USB 驱动程序,在手机的开发者设置中激活 USB 调试,并授权 PC 调试手机(通过设备上的提示。)完成后,您将能够使用adb pushadb pull命令复制文件和目录,以及通过adb shell <command>(例如adb shell ls /sdcard/)各种Linux shell 命令来导航手机上的目录结构。

编辑 2017 年 3 月 20 日 10:18
社区?
1 人

2013 年11 月 21 日 16:14 回答Chahk

18.5k

上面答案中提到的应用程序在我看来非常有限,因为它的年龄。