I have the same problem, and thanks to @Stephen Brodie's answer in #72842042, I successed to copy a picture to my PC with windows10.
@Stephen Brodie menstioned:
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
Below is my code according to @Stephen Brodie's.
Source file: \Computer\Apple iPhone\Internal Storage\DCIM\100APPLE\IMG_0199.JPG
Destination folder: C:\Users\Administrator\Desktop\myFolder\savedImages
from win32com.shell import shell, shellcon
import pythoncom
# get the PIDL of source file and the ShellObject of the folder in which source file is
# and the PIDL of the folder
desktop = shell.SHGetDesktopFolder()
for pidl in desktop:
if desktop.GetDisplayNameOf(pidl, shellcon.SHGDN_NORMAL) == "Computer":
pidl_get = pidl
break
folder = desktop.BindToObject(pidl_get, None, shell.IID_IShellFolder)
for pidl in folder:
if folder.GetDisplayNameOf(pidl, shellcon.SHGDN_NORMAL) == "Apple iPhone":
pidl_get = pidl
break
folder = folder.BindToObject(pidl_get, None, shell.IID_IShellFolder)
for pidl in folder:
if folder.GetDisplayNameOf(pidl, shellcon.SHGDN_NORMAL) == "Internal Storage":
pidl_get = pidl
break
folder = folder.BindToObject(pidl_get, None, shell.IID_IShellFolder)
for pidl in folder:
if folder.GetDisplayNameOf(pidl, shellcon.SHGDN_NORMAL) == "DCIM":
pidl_get = pidl
break
folder = folder.BindToObject(pidl_get, None, shell.IID_IShellFolder)
for pidl in folder:
if folder.GetDisplayNameOf(pidl, shellcon.SHGDN_NORMAL) == "100APPLE":
pidl_get = pidl
break
folderPIDL = pidl_get
folder = folder.BindToObject(pidl_get, None, shell.IID_IShellFolder)
NOW we have
folderPIDL
: PIDL of the folder in which the source file is
folder
: the ShellObject of the folder in which the source file is
for pidl in folder:
if folder.GetDisplayNameOf(pidl, shellcon.SHGDN_NORMAL) == "IMG_0199.JPG":
imgPIDL = pidl
# imgPIDL: PIDL of the source file
And we get imgPIDL
.
(Remember to enable windows10 to show extensions in File Explorer.
Otherwise, folder.GetDisplayNameOf(pidl, shellcon.SHGDN_NORMAL)
will show "IMG_0199"
instead of "IMG_0199.JPG".)
# then get the ShellObject of Destination folder
for pidl in desktop:
if desktop.GetDisplayNameOf(pidl, shellcon.SHGDN_NORMAL) == "myFolder":
pidl_dst = pidl
break
dstFolder = desktop.BindToObject(pidl_dst, None, shell.IID_IShellFolder)
for pidl in dstFolder:
if folder.GetDisplayNameOf(pidl, shellcon.SHGDN_NORMAL) == "savedImages":
pidl_dst = pidl
break
dstFolder = folder.BindToObject(pidl_dst, None, shell.IID_IShellFolder)
All we need for copy file are 4 var: folderPIDL, folder, imgPIDL and dstFolder
Start to Copy file (@Stephen Brodie's code)
fidl = shell.SHGetIDListFromObject(folder) #Grab the PIDL from the folder object
didl = shell.SHGetIDListFromObject(dstFolder) #Grab the PIDL from the folder object
si = shell.SHCreateShellItem(fidl, None, imgPIDL) #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
And success!!
At first, I tried to skip fidl
and didl
, and just used si
and dst
. I failed. The error message said last line pfo.PerformOperations()
cannot run. Maybe SHGetIDListFromObject()
is essential for changing ShellObject to IDList.
Besides, my PC show Chinese character "本機" instead of "Computer". All I need is to change "Computer" to "本機" in the codes above.