Jump to content
queensoft

Portable device (Android phone) - copy files

Recommended Posts

Connect Android phone > enable USB file transfer > go to My Computer, there's an icon, but no drive letter - this is normal.

Open phone icon > go to Internal Storage > go to DCIM > copy all files and folders to computer.

Now, I want a quick AutoIt script / windows batch to do this automatically.

Get USB path with this - it works OK:

#include <WinAPICom.au3>

Global Const $sCLSID_PortableDeviceManager = "{0af10cec-2ecd-4b92-9581-34f6ae0637f3}"
Global Const $sIID_IPortableDeviceManager = "{a1567595-4c2f-4574-a6fa-ecef917b9a40}"
Global Const $sTagIPortableDeviceManager = "GetDevices hresult(ptr;dword*); RefreshDeviceList hresult(); " & _
        "GetDeviceFriendlyName hresult(wstr;wstr;dword*); GetDeviceDescription hresult(wstr;wstr;dword*); " & _
        "GetDeviceManufacturer hresult(wstr;wstr;dword*); GetDeviceManufacturer hresult(wstr;wstr;ptr;dword*dword*); " & _
        "GetPrivateDevices hresult(ptr;dword*)"

Global Enum $eDevID, $eDevName, $eDevManufacturer, $eDevDescription


Local $aPnPDevices = GetPortableDevices()
If IsArray($aPnPDevices) Then _ArrayDisplay($aPnPDevices)

;~ Success: Return 0
;~ Failure: Return 2DArray [n][4] |;[n][0]$eDevID, [n][1]$eDevName, [n][2]$eDevManufacturer,[n][3] $eDevDescription
Func GetPortableDevices()
    Local $aDevicesInfo[0][0] ;[n][0]$eDevID, [n][1]$eDevName, [n][2]$eDevManufacturer,[n][3] $eDevDescription
    Local $oPortableDeviceManager = 0
    Local $SizeofArray = 0
    Local $hr = 0x80004005 ;E_Fail Just to Initialized <0
    Local $taPnPDeviceIDs = 0
    Local $tName = 0
    $oPortableDeviceManager = ObjCreateInterface($sCLSID_PortableDeviceManager, $sIID_IPortableDeviceManager, $sTagIPortableDeviceManager)
    If Not IsObj($oPortableDeviceManager) Then Return 0

    If FAILED($oPortableDeviceManager.GetDevices(Null, $SizeofArray)) Then Return 0
    If $SizeofArray < 1 Then Return 0
    $taPnPDeviceIDs = DllStructCreate("ptr[" & $SizeofArray & "]")
    If FAILED($oPortableDeviceManager.GetDevices(DllStructGetPtr($taPnPDeviceIDs), $SizeofArray)) Then Return 0

    ReDim $aDevicesInfo[$SizeofArray][4]

    For $i = 0 To $SizeofArray - 1
        $tName = DllStructCreate("wchar[512]", DllStructGetData($taPnPDeviceIDs, 1, $i + 1))
        $aDevicesInfo[$i][$eDevID] = DllStructGetData($tName, 1)
        $aDevicesInfo[$i][$eDevName] = _GetFriendlyName($oPortableDeviceManager, $aDevicesInfo[$i][$eDevID])
        $aDevicesInfo[$i][$eDevManufacturer] = _GetDeviceManufacturer($oPortableDeviceManager, $aDevicesInfo[$i][$eDevID])
        $aDevicesInfo[$i][$eDevDescription] = _GetDeviceDescription($oPortableDeviceManager, $aDevicesInfo[$i][$eDevID])
        $tName = 0
        _WinAPI_CoTaskMemFree(DllStructGetData($taPnPDeviceIDs, 1, $i + 1))
    Next
    Return $aDevicesInfo

EndFunc   ;==>GetPortableDevices



Func _GetDeviceManufacturer($oInterface, $PnPDeviceID)
    Local $sString = ""
    $oInterface.GetDeviceManufacturer($PnPDeviceID, $sString, 128)
    Return $sString
EndFunc   ;==>_GetDeviceManufacturer


Func _GetDeviceDescription($oInterface, $PnPDeviceID)
    Local $sString = ""
    Local Const $Size = 128
    $oInterface.GetDeviceDescription($PnPDeviceID, $sString, 128)
    Return $sString
EndFunc   ;==>_GetDeviceDescription


Func _GetFriendlyName($oInterface, $PnPDeviceID)
    Local $sString = ""
    Local Const $Size = 128
    $oInterface.GetDeviceFriendlyName($PnPDeviceID, $sString, 128)
    Return $sString
EndFunc   ;==>_GetFriendlyName

Func _GetProperty($oInterface, $PnPDeviceID)
    Local $sString = ""
    Local Const $Size = 128
    $oInterface.GetDeviceFriendlyName($PnPDeviceID, $sString, 128)
    Return $sString
EndFunc   ;==>_GetProperty

Func FAILED($hr)
    Return ($hr < 0)
EndFunc   ;==>FAILED

Path looks like this:

\\?\usb#vid_0e8d&pid_201d&mi_00#7&37c4bb9&0&0000#{6ac27878-a6fa-4155-ba85-f98f491d4f33}

I can open this in a Windows Explorer windows and it works ok.

Now, search for files using AutoIt - does not work:

#include <GUIConstantsEx.au3>
#include <Array.au3>
#include <File.au3>

Local $f


$f = _RecFileListToArray("\\?\usb#vid_0e8d&pid_201d&mi_00#7&37c4bb9&0&0000#{6ac27878-a6fa-4155-ba85-f98f491d4f33}", "*.*", 0, 1, 1)
_ArrayDisplay($f)

; Name...........: _RecFileListToArray
; Description ...: Lists files and\or folders in a specified path (Similar to using Dir with the /B Switch)
; Syntax.........: _RecFileListToArray($sPath[, $sFilter = "*"[, $iFlag = 0[, $iRecur = 0[, $iFullPath = 0]]]])
; Parameters ....: $sPath   - Path to generate filelist for.
;                 $sFilter - Optional the filter to use, default is *. Search the Autoit3 helpfile for the word "WildCards" For details.
;                 $iFlag   - Optional: specifies whether to return files folders or both
;                 |$iFlag=0 (Default) Return both files and folders
;                 |$iFlag=1 Return files only
;                 |$iFlag=2 Return Folders only
;                 $iRecur  - Optional: specifies whether to search in subfolders
;                 |$iRecur=0 (Default) Do not search in subfolders
;                 |$iRecur=1 Search in subfolders
;                 $iFullPath  - Optional: specifies whether to include initial path in result string
;                 |$iFullPath=0 (Default) Do not include initial path
;                 |$iFullPath=1 Include initial path
; Return values .: @Error - 1 = Path not found or invalid
;                 |2 = Invalid $sFilter
;                 |3 = Invalid $iFlag
;                 |4 = Invalid $iRecur
;                 |5 = Invalid $iFullPath
;                 |6 = No File/Folder Found
; Author ........: SolidSnake <MetalGX91 at GMail dot com>
; Modified.......: 22 Jan 09 by Melba23 - added recursive search and full path options
; Remarks .......: The array returned is one-dimensional and is made up as follows:
;                               $array[0] = Number of Files\Folders returned
;                               $array[1] = 1st File\Folder
;                               $array[2] = 2nd File\Folder
;                               $array[3] = 3rd File\Folder
;                               $array[n] = nth File\Folder
; Related .......:
; Link ..........;
; Example .......; Yes
; ====================================================================================================

;Special Thanks to Helge and Layer for help with the $iFlag update
; speed optimization by code65536
;===============================================================================
Func _RecFileListToArray($sPath, $sFilter = "*", $iFlag = 0, $iRecur = 0, $iFullPath = 0)
    Local $asFileList[1], $sFullPath
    If Not FileExists($sPath) Then Return SetError(1, 1, "")
    If StringRight($sPath, 1) <> "\" Then $sPath = $sPath & "\"
    If (StringInStr($sFilter, "\")) Or (StringInStr($sFilter, "/")) Or (StringInStr($sFilter, ":")) Or (StringInStr($sFilter, ">")) Or (StringInStr($sFilter, "<")) Or (StringInStr($sFilter, "|")) Or (StringStripWS($sFilter, 8) = "") Then Return SetError(2, 2, "")
    If Not ($iFlag = 0 Or $iFlag = 1 Or $iFlag = 2) Then Return SetError(3, 3, "")
    If Not ($iRecur = 0 Or $iRecur = 1) Then Return SetError(4, 4, "")
    If $iFullPath = 0 Then
        $sFullPath = $sPath
    ElseIf $iFullPath = 1 Then
        $sFullPath = ""
    Else
        Return SetError(5, 5, "")
    EndIf
    _FLTA_Search($sPath, $sFilter, $iFlag, $iRecur, $sFullPath, $asFileList)
    If $asFileList[0] = 0 Then Return SetError(6, 6, "")
    Return $asFileList
EndFunc  ;==>_FileListToArray

; #INTERNAL_USE_ONLY#=================================================================================

; Name...........: _FLTA_Search
; Description ...: Searches folder for files and then recursively searches in subfolders
; Syntax.........: _FLTA_Search($sStartFolder, $sFilter, $iFlag, $iRecur, $sFullPath, ByRef $asFileList)
; Parameters ....: $sStartFolder - Value passed on from UBound($avArray)
;                 $sFilter - As set in _FileListToArray
;                 $iFlag - As set in _FileListToArray
;                 $iRecur - As set in _FileListToArray
;                 $sFullPath - $sPath as set in _FileListToArray
;                 $asFileList - Array containing found files/folders
; Return values .: None
; Author ........: Melba23 based on code from _FileListToArray by SolidSnake <MetalGX91 at GMail dot com>
; Modified.......:
; Remarks .......: This function is used internally by _FileListToArray.
; Related .......:
; Link ..........;
; Example .......;
; ====================================================================================================

Func _FLTA_Search($sStartFolder, $sFilter, $iFlag, $iRecur, $sFullPath, ByRef $asFileList)

    Local $hSearch, $sFile

    If StringRight($sStartFolder, 1) <> "\" Then $sStartFolder = $sStartFolder & "\"
; First look for filtered files/folders in folder
    $hSearch = FileFindFirstFile($sStartFolder & $sFilter)
    If $hSearch > 0 Then
        While 1
            $sFile = FileFindNextFile($hSearch)
            If @error Then ExitLoop
            Switch $iFlag
                Case 0; Both files and folders
                    If $iRecur And StringInStr(FileGetAttrib($sStartFolder & $sFile), "D") <> 0 Then ContinueLoop
                Case 1; Files Only
                    If StringInStr(FileGetAttrib($sStartFolder & $sFile), "D") <> 0 Then ContinueLoop
                Case 2; Folders only
                    If StringInStr(FileGetAttrib($sStartFolder & $sFile), "D") = 0 Then ContinueLoop
            EndSwitch
            If $iFlag = 1 And StringInStr(FileGetAttrib($sStartFolder & $sFile), "D") <> 0 Then ContinueLoop
            If $iFlag = 2 And StringInStr(FileGetAttrib($sStartFolder & $sFile), "D") = 0 Then ContinueLoop
            _FLTA_Add($asFileList, $sFullPath, $sStartFolder, $sFile)
        WEnd
        FileClose($hSearch)
        ReDim $asFileList[$asFileList[0] + 1]
    EndIf

    If $iRecur = 1 Then
    ; Now look for subfolders
        $hSearch = FileFindFirstFile($sStartFolder & "*.*")
        If $hSearch > 0 Then
            While 1
                $sFile = FileFindNextFile($hSearch)
                If @error Then ExitLoop
                If StringInStr(FileGetAttrib($sStartFolder & $sFile), "D") And ($sFile <> "." Or $sFile <> "..") Then
                ; If folders needed, add subfolder to array
                    If $iFlag <> 1 Then _FLTA_Add($asFileList, $sFullPath, $sStartFolder, $sFile)
                ; Recursive search of this subfolder
                    _FLTA_Search($sStartFolder & $sFile, $sFilter, $iFlag, $iRecur, $sFullPath, $asFileList)
                EndIf
            WEnd
            FileClose($hSearch)
        EndIf
    EndIf

EndFunc

; #INTERNAL_USE_ONLY#=================================================================================

; Name...........: _FLTA_Add
; Description ...: Searches folder for files and then recursively searches in subfolders
; Syntax.........: _FLTA_Add(ByRef $asFileList, $sFullPath, $sStartFolder, $sFile)
; Parameters ....: $asFileList - Array containing found files/folders
;                 $sFullPath - $sPath as set in _FileListToArray
;                 $sStartFolder - Value passed on from UBound($avArray)
;                 $sFile - Full path of file/folder to add to $asFileList
; Return values .: Function only changes $asFileList ByRef
; Author ........: Melba23 based on code from _FileListToArray by SolidSnake <MetalGX91 at GMail dot com>
; Modified.......:
; Remarks .......: This function is used internally by _FileListToArray.
; Related .......:
; Link ..........;
; Example .......;
; ====================================================================================================

Func _FLTA_Add(ByRef $asFileList, $sFullPath, $sStartFolder, $sFile)

    Local $sAddFolder

    $asFileList[0] += 1
    If UBound($asFileList) <= $asFileList[0] Then ReDim $asFileList[UBound($asFileList) * 2]
    If $sFullPath = "" Then
        $sAddFolder = $sStartFolder
    Else
        $sAddFolder = StringReplace($sStartFolder, $sFullPath, "")
    EndIf
    $asFileList[$asFileList[0]] = $sAddFolder & $sFile

EndFunc

File copy using Autoit - does not work:

FileCopy("\\?\usb#vid_0e8d&pid_201d&mi_00#7&37c4bb9&0&0000#{6ac27878-a6fa-4155-ba85-f98f491d4f33}\Internal storage\DCIM\Camera MX\PHOTO_20161007_123935.jpg", 'd:\Diverse 2\654\0\')

Copy using Windows batch - does not work:

xcopy /Y /E "\\?\usb#vid_0e8d&pid_201d&mi_00#7&37c4bb9&0&0000#{6ac27878-a6fa-4155-ba85-f98f491d4f33}\Internal storage\DCIM\*.*" "d:\Diverse 2\654\0\"

 

Edited by queensoft

Share this post


Link to post
Share on other sites

Can't this part (dll files - only for copy operation), be extracted from larger development kit and accessed with AutoIt ?

Or use any other file copy utility, like robocopy or similar ?

 

Found this, first step working - I get a list of drives (including android phone) and a list of files&folders: https://gist.github.com/cveld/8fa339306f8504095815

Now the hard part, not working now, very limited Powershell knowledge right now: change path, copy files....

Edited by queensoft

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • By Inpho
      Hi All,
      I didn't know where to put this; my apologies if this is the wrong location.
      When you plug a Samsung mobile device (phone, tablet, etc.) into the USB of a Windows PC, you can right-click the device in My Computer and select Properties. Here, it will show you the correct serial number of the device. Clearly Windows doesn't use adb to get the SN so I'm stuck at how to get the SN without adb and where the device doesn't have a drive letter assigned to it.
      When I last picked this up, I tried seemingly everything I could from wmi(?) and winmgmts(?) but either it's hidden cloak-and-dagger style or I can't see the forest for the trees...
      Does anyone know what API Windows uses when getting the serial number of a device Windows calls a Portable Media Player?

    • By rudi
      Hello,
       
      I found a couple of threads asking quite similar questions, but without finding a "straight" solution to Access the internal phone storage as well as the plugged in SD-Card.
       
      While the SD Card is quite an easy Job (shutdown phone, remove SD, plug into some Card Reader, Access it using a drive letter), the internal storage isn't accessible this way.
       
      Of course I *CAN* Access all the (regular visible) Content, when connected to a Windows box.
       
      But this way I cannot estimate, where all the space was eaten up. So I'd like to know, how to address the "root" Folder of the internal storage of my Android Phone to get it's subfolders and files. Going through the whole Folder tree recursively isn't my Problem, it's just howto address the very first Folder and then to read all files (with sizes) and names of the subfolders.
       
       
      Regards, Rudi.
    • By wisem2540
      I am a huge autoit fan and have written several graphical apps.  I would love to get started building simple and complex android apps.  I am hoping someone here can recommend a good platform to get started with.  Preferably something that had an Autoit-like feel
    • By XinYoung
      HI! ... this is a big one (at least for me) 
      You guys previously helped me copy the used range in column A and paste them into a Website one at a time in a loop. Cool! Now, for another function, I have 2 columns, A and B, and two input boxes in the Website. I'm having a hard time replicating the loop for the 2 columns. 
      This is how I'm opening the Excel workbook (copied from the previous function that only had 1 column). I need to also get the used range in column B.
      Func OpenExcelForCopy() Global $aBBTableData Global $oExcel = _Excel_Open() Global $oWorkbook = _Excel_BookOpen($oExcel, $ChosenFileName, Default, True, True) $oExcel.Sheets("CopyCourses").Activate ;~ Get all used cells in column A:A Global $aSearchItems = _Excel_RangeRead($oWorkbook, 1, $oWorkbook.Sheets("CopyCourses").Usedrange.Columns("A:A")) ;~ Duplicate the $aSearchItems Array Global $aSearchResult = $aSearchItems ;~ Loop through the array starting at 0 until the end of the array which is (Ubound($aSearchItems) - 1) For $i = 0 To UBound($aSearchItems) - 1 $aSearchResult[$i] = SearchCourseForCopy($aSearchItems[$i]) Next _Excel_RangeWrite($oWorkbook, Default, $aSearchResult, "C1") Finished() EndFunc ;==>OpenExcelForCopy Then we eventually get here. I don't think anything needs to change here but I'm not sure. This is where I paste the data from Column A into an input field (which is a search tool in a website). If the search is good, then we get to the tricky part...
      ;~ OK, we logged in and we searched for a course. Lets COPY it! Func CopyCourseBegin() Local $sResult $iSearchIndex = _ArraySearch($aBBTableData, "Course ID", 0, 0, 0, 1, 1, 0) ;~ If the course was not found, do this. If $iSearchIndex = -1 Then ;~ MsgBox(4096, "Search Error", "Item not found") $sResult = "Source Not Found" _Excel_RangeWrite($oWorkbook, Default, $aSearchResult, "C1") ;~ Now go back to the Excel sheet and search for the next one. ;~ If the course was found, begin the COPY process. Else For $i = 0 To UBound($aSearchItems) - 1 $aSearchResult[$i] = CopyCourseNow($aSearchItems[$i]) Next $sResult = "Copied" _Excel_RangeWrite($oWorkbook, Default, $aSearchResult, "C1") EndIf Return $sResult EndFunc ;==>CopyCourseBegin This is the "tricky part" where I'm confused. I can copy and paste what's in column A just fine, but I can't manage to replicate it for column B. I need to paste whats in Column B into "destinationCourseId"
      ;~ The course search was successful. COPY the course now. Func CopyCourseNow($_sSearchResult) ;~ Navigate to the course copy page. _IENavigate($oIE, $urlBBCourseCopy) ;~ Copy the SOURCE course ID from the Excel sheet ;~ Paste whats copied from column A into the Source Course ID text box Local $oForm = _IEGetObjByName($oIE, "selectCourse") Local $oSearchString = _IEFormElementGetObjByName($oForm, "sourceCourseId") _IEFormElementSetValue($oSearchString, $_sSearchResult) ;~ Paste whats copied from column B into the Destination Course ID text box ?!?!?!?! Local $oForm = _IEGetObjByName($oIE, "selectCourse") Local $oSearchString = _IEFormElementGetObjByName($oForm, "destinationCourseId") _IEFormElementSetValue($oSearchString, $_sSearchResult) ;~ Just exit cause im stuck :( _Exit() EndFunc ;==>CopyCourseNow After I paste the data from column A into "sourceCourseId" and column B into "destinationCourseId", I'll make it do some stuff. Then I need it to loop around until the used ranges in column A & B is finished.
      Does the entire code need to change now that there's two columns?
       
       
    • By vin1
      i have a script that selects  a text file and deletes a line (text input required) in the text file selected
      i have to make it remove all lines found on a file i name, toRemoveLines.txt
      it has to remove lines from all text files found in a folder
      this is the script that has to be modified
      where it says "select file" it has to be "select folder"
      where it says "line text input" it has to be all lines from a text file
      #Include <File.au3> Global $success = False $file_name = FileOpenDialog("Select file", @ScriptDir, "All files (*.*)", 1+4) $line_text_input = InputBox("Line's text", "Line must contain following text:", "line contains this text") $file_count_lines = _FileCountLines($file_name) for $i = 0 to $file_count_lines $Lines_text_output = FileReadLine($file_name, $i) if StringInStr($Lines_text_output, $line_text_input) then _FileWriteToLine($file_name, $i, "", 1) $success = True ExitLoop EndIf Next if $success = True Then MsgBox(0, "Success", "Line has been deleted") Else MsgBox(0, "Failure", "Line wasn't found") EndIf  
×
×
  • Create New...