Shell API问题:通过别名删除文件无法移入回收站,如何修改代码?
解决Subst虚拟驱动器路径文件删除无法移入回收站的问题
问题根源
当使用subst创建的虚拟驱动器路径(如V:\...)时,IFileOperation无法正确关联该路径到对应物理驱动器的回收站容器,导致即使设置了回收站相关操作标志,文件也会被直接永久删除,而非移入回收站。这是因为虚拟驱动器的逻辑路径并未与物理驱动器的回收站建立映射关系。
解决方案
核心思路是:在执行删除操作前,将基于虚拟路径的IShellItem转换为物理真实路径对应的IShellItem,让IFileOperation能正确识别文件所属的物理驱动器,从而触发正常的回收站逻辑。
修改后的代码
首先添加一个辅助函数,用于将原IShellItem转换为真实路径对应的IShellItem:
HRESULT GetRealPathShellItem(const CComPtr<IShellItem>& pOriginalItem, CComPtr<IShellItem>& pRealItem) { if (!pOriginalItem || !pRealItem) return E_INVALIDARG; // 获取文件的物理真实路径 PWSTR pszRealPath = nullptr; HRESULT hr = pOriginalItem->GetDisplayName(SIGDN_FILESYSPATH, &pszRealPath); if (FAILED(hr)) return hr; // 用真实路径重新创建IShellItem hr = SHCreateItemFromParsingName(pszRealPath, nullptr, IID_PPV_ARGS(&pRealItem)); CoTaskMemFree(pszRealPath); return hr; }
然后修改原Delete函数,在删除前完成IShellItem的转换:
bool Delete(const ::CComPtr<IShellItem>& pShellItem, bool permanently) { ::CComPtr<IFileOperation> pFileOperation; // 初始化文件操作对象 HRESULT hr = ::CoCreateInstance(CLSID_FileOperation, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pFileOperation)); if (FAILED(hr)) return false; // 转换为真实路径对应的ShellItem,处理subst虚拟驱动器场景 CComPtr<IShellItem> pRealShellItem; hr = GetRealPathShellItem(pShellItem, pRealShellItem); if (FAILED(hr)) return false; // 设置操作标志 DWORD fileOpFlags = FOF_SILENT | FOF_NO_UI | FOF_NOERRORUI | FOF_NOCONFIRMATION | FOFX_EARLYFAILURE | FOFX_SHOWELEVATIONPROMPT; if (!permanently) { if (WOSHelper_MSWindows::GetWindowsVersion() >= WOSHelper_MSWindows::IEVersion::IE_Win8) { fileOpFlags |= FOFX_ADDUNDORECORD | FOFX_RECYCLEONDELETE; } else { fileOpFlags |= FOF_ALLOWUNDO; } } hr = pFileOperation->SetOperationFlags(fileOpFlags); if (FAILED(hr)) return false; // 使用真实路径的ShellItem执行删除 hr = pFileOperation->DeleteItem(pRealShellItem, nullptr); if (FAILED(hr)) return false; hr = pFileOperation->PerformOperations(); if (FAILED(hr)) return false; return true; }
关键说明
SIGDN_FILESYSPATH标志会自动解析subst虚拟驱动器、网络映射驱动器等逻辑路径,返回文件的物理真实路径。- 基于真实路径重新创建
IShellItem后,IFileOperation能正确识别文件所属的物理驱动器,从而将文件移入对应回收站。 - 保留了原有的Windows版本判断逻辑,确保不同系统版本下的回收站标志设置符合微软规范。
内容的提问来源于stack exchange,提问作者Jean-Milost Reymond
相关产品推荐
相关产品推荐

