Windows 7下能否让SHFileOperation支持无盘符路径的文件复制?
问题:能否让SHFileOperation在Windows 7中处理无盘符/非卷标路径的文件?
背景:Windows Shell中的SHFileOperation已被IFileOperation取代(官方说明:“复制、移动、重命名或删除文件系统对象,该函数在Windows Vista中被IFileOperation替代”)。但在需支持的Windows 7系统中,IFileOperation::CopyItem并不兼容所有设备类型,因此希望继续使用SHFileOperation实现带原生Windows复制对话框的文件复制功能。
当前遇到的问题:SHFileOperation无法处理类似Computer\Phone\card\DCIM\test.jpg这类无盘符、非卷标格式的路径,执行时返回错误码124,无法完成复制。
示例代码
from win32com.shell import shell, shellcon dest = r"E:\Temp" for src in [r"E:\Temp2\test.txt", r"Computer\Phone\card\DCIM\test.jpg"]: result, aborted = shell.SHFileOperation((0, shellcon.FO_COPY, src, dest, shellcon.FOF_NOCONFIRMMKDIR, None, None)) print(result, aborted)
执行结果
E:\Temp2\test.txt 0 False # success Computer\Phone\card\DCIM\test.jpg 124 False # not working
解决方案
SHFileOperation本身不支持直接解析这类Shell命名空间路径(如手机、外接设备这类无盘符路径),必须先将路径转换为ITEMIDLIST (PIDL),再传递给函数处理。
具体实现步骤:
- 使用
shell.SHParseDisplayName将Shell格式路径转换为PIDL(Shell内部用于标识对象的唯一ID列表)。 - 将PIDL传入
SHFileOperation,替代原字符串路径作为源参数。
修改后的示例代码(基于pywin32):
from win32com.shell import shell, shellcon def copy_shell_path(src_shell_path, dest_path): # 解析Shell路径为PIDL pidl, _, _ = shell.SHParseDisplayName(src_shell_path, 0) if not pidl: return -1, True # 传入PIDL执行复制操作 result, aborted = shell.SHFileOperation( (0, shellcon.FO_COPY, pidl, dest_path, shellcon.FOF_NOCONFIRMMKDIR, None, None) ) return result, aborted dest = r"E:\Temp" for src in [r"E:\Temp2\test.txt", r"Computer\Phone\card\DCIM\test.jpg"]: result, aborted = copy_shell_path(src, dest) print(f"{src:<35} {result:<3} {aborted}")
注意事项:
- 错误码124对应
ERROR_INVALID_NAME,本质是SHFileOperation无法识别原始字符串路径的格式。 - 并非所有Shell命名空间对象都支持通过
SHFileOperation复制,部分设备可能依赖特定Shell扩展,但转换为PIDL是让函数识别这类路径的必要前提。 - 如果上述方法仍失效,可能需要直接调用底层Shell API,或通过
IShellFolder接口操作目标对象。
内容的提问来源于stack exchange,提问作者Basj
相关产品推荐
相关产品推荐

