Delphi递归删除文件夹至recycle bin遇zip file报错120求解决
解决Delphi中使用ShFileOperation删除Zip文件到回收站报错120的问题
问题原因
Windows会将Zip文件识别为Shell虚拟压缩文件夹,ShFileOperation函数无法直接处理这类虚拟命名空间对象,因此会返回错误码120(ERROR_CALL_NOT_IMPLEMENTED,即函数不受支持),即便修改文件扩展名也无法改变系统对其的虚拟文件夹识别属性。
解决方案
使用Windows Vista及以后官方推荐的IFileOperation接口替代ShFileOperation,该接口对Shell命名空间中的各类对象(包括压缩文件夹)支持更完善,能正确将其删除至回收站。
修改后的代码实现
uses Windows, ActiveX, ShellAPI, ShlObj; function RecycleFileToBin(const FileName: string): Boolean; var FileOp: IFileOperation; FileItem: IShellItem; hr: HRESULT; begin Result := False; // 初始化COM环境 if CoInitialize(nil) = S_OK then try // 创建IFileOperation实例 hr := CoCreateInstance(CLSID_FileOperation, nil, CLSCTX_ALL, IID_IFileOperation, FileOp); if Succeeded(hr) then begin // 设置操作标志:允许撤销(到回收站)、不弹出确认框、不显示错误UI FileOp.SetOperationFlags(FOF_ALLOWUNDO or FOF_NOCONFIRMATION or FOF_NOERRORUI); // 将文件路径转换为Shell命名空间标准对象 hr := SHCreateItemFromParsingName(PChar(FileName), nil, IID_IShellItem, FileItem); if Succeeded(hr) then begin // 添加删除任务 hr := FileOp.DeleteItem(FileItem, nil); if Succeeded(hr) then begin // 执行实际删除操作 hr := FileOp.PerformOperations; Result := Succeeded(hr); end; end; end; finally CoUninitialize; end; end;
代码说明
- COM环境管理:
IFileOperation基于COM架构,必须通过CoInitialize和CoUninitialize完成环境的初始化与释放。 - 操作标志配置:通过
SetOperationFlags保留了原代码的核心行为——允许撤销至回收站、无确认弹窗、不显示错误提示。 - ShellItem转换:
SHCreateItemFromParsingName将文件路径转换为Shell命名空间的标准对象IShellItem,能正确识别并处理压缩文件夹这类虚拟对象。 - 执行删除流程:先通过
DeleteItem添加删除任务,再调用PerformOperations执行实际的删除操作。
兼容性说明
该代码支持Windows Vista及以上系统(Win7/8/10/11均适用)。若需兼容已停止官方支持的Windows XP,可保留原ShFileOperation代码作为降级方案,优先尝试IFileOperation,失败后再回退到原方法。
内容的提问来源于stack exchange,提问作者user3140961
相关产品推荐
相关产品推荐

