I've been trying to find a way to copy files off an iPhone but despite being able to list files within it using win32com.shell GetDisplayNameOf and BindToObject, I can't seem to find any way of copying files using only the pidl reference.
Unfortunately when the iPhone is connected to Windows it doesn't mount as a drive letter, requiring you to use the PIDL reference rather than a full path. However after much Googling, I can't seem to find a way of copying using only the PIDL reference.
"path = shell.SHGetPathFromIDList(pidl)" seems to be a potential option to find a filesystem path from a PIDL, however as the iPhone doesn't mount to a filesystem path, this always returns an error when given a PIDL value.
Example code I've used so far (taken from How can I iterate across the photos on my connected iPhone from Windows 7 in Python?):
from win32com.shell import shell, shellcon
desktop = shell.SHGetDesktopFolder()
for pidl in desktop:
if desktop.GetDisplayNameOf(pidl, shellcon.SHGDN_NORMAL) == "This PC":
# path = shell.SHGetPathFromIDList(pidl)
print path
break
folder = desktop.BindToObject(pidl, None, shell.IID_IShellFolder)
for pidl in folder:
if folder.GetDisplayNameOf(pidl, shellcon.SHGDN_NORMAL) == "My iPhone":
break
folder = folder.BindToObject(pidl, None, shell.IID_IShellFolder)
for pidl in folder:
if folder.GetDisplayNameOf(pidl, shellcon.SHGDN_NORMAL) == "Internal Storage":
break
folder = folder.BindToObject(pidl, None, shell.IID_IShellFolder)
for pidl in folder:
if folder.GetDisplayNameOf(pidl, shellcon.SHGDN_NORMAL) == "DCIM":
break
# Each of the image folders
folder = folder.BindToObject(pidl, None, shell.IID_IShellFolder)
for pidl in folder:
# print folder.GetDisplayNameOf(pidl, shellcon.SHGDN_NORMAL)
files = folder.BindToObject(pidl, None, shell.IID_IShellFolder)
for curfile in files:
current_file = folder.GetDisplayNameOf(pidl, shellcon.SHGDN_NORMAL) + "\\" + files.GetDisplayNameOf(curfile, shellcon.SHGDN_NORMAL)
folder.BindToObject(pidl, )
Does anyone have any ideas?
Key references I've used so far: Example code that correctly reads the filesystem using PIDLs: How can I iterate across the photos on my connected iPhone from Windows 7 in Python?
Example of how to list files off an iPhon, but no details of how to copy them: https://github.com/dblume/list-photos-on-phone/blob/master/list-photos-on-phone.py
Not quite sure of the links to stuff. But I have been able to copy files once I have a PIDL. You have to create a ShellItem of the file and the destination. Then use the IFileOperation. I think it was mostly a lot of googling and looking up the microsoft MSDN docs.
Anyway here's the code. Hopefully it helps!
from win32com.shell import shell, shellcon
import pythoncom
#fo is the folder IShellFolder object
#dsk is the destination IShellFolder object
#fi is the PIDL of the item you wish to copy (eg. the photo on your iPhone)
fidl = shell.SHGetIDListFromObject(fo) #Grab the PIDL from the folder object
didl = shell.SHGetIDListFromObject(dsk) #Grab the PIDL from the folder object
si = shell.SHCreateShellItem(fidl, None, fi) #Create a ShellItem of the source file
dst = shell.SHCreateItemFromIDList(didl)
#Python IFileOperation
pfo = pythoncom.CoCreateInstance(shell.CLSID_FileOperation,None,pythoncom.CLSCTX_ALL,shell.IID_IFileOperation)
pfo.SetOperationFlags(shellcon.FOF_NOCONFIRMATION)
pfo.CopyItem(si, dst, "Destination Name.jpg") # Schedule an operation to be performed
success = pfo.PerformOperations() #perform operation
Good luck with your project!