首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

VC++ 實現檔案移至回收站而非永久刪除:SHFileOperation 完整指南

     編輯:VC 教學

為什麼不用 CFile::Remove?

CFile::Remove 永久刪除檔案,無法復原。使用者習慣從回收站還原誤刪檔案,專業應用應尊重此行為模式。

核心 API:SHFileOperation

int SHFileOperation(LPSHFILEOPSTRUCT lpFileOp);

單一結構體參數控制所有行為,支援複製、移動、重命名、刪除,並自動顯示系統標準進度對話框。

SHFILEOPSTRUCT 關鍵欄位

欄位型別說明
hwndHWND擁有者視窗句柄,進度對話框置中用
wFuncUINT操作類型:FO_COPY/FO_MOVE/FO_RENAME/FO_DELETE
pFromLPCSTR來源路徑,多檔案以 \0 分隔,結尾雙 \0\0
pToLPCSTR目標路徑 (移動/複製/重命名用),刪除時可為 NULL
fFlagsFILEOP_FLAGS行為旗標組合 (見下表)
lpszProgressTitleLPCSTR進度對話框標題

關鍵旗標 fFlags

旗標作用
FOF_ALLOWUNDO刪除至回收站 (核心旗標)
FOF_NOCONFIRMATION覆蓋/刪除不彈出確認對話框
FOF_SILENT不顯示進度對話框
FOF_NOERRORUI錯誤時不顯示 UI
FOF_RENAMEONCOLLISION名稱衝突自動重命名
FOF_FILESONLY通配符僅匹配檔案,不含目錄
FOF_WANTMAPPINGHANDLE回傳實際操作檔案對應清單

完整範例:將資料夾移至回收站

void CMyView::OnFileDeleteToRecycle() {
    SHFILEOPSTRUCT fos = {0};
    fos.hwnd = m_hWnd;
    fos.wFunc = FO_DELETE;
    
    // 來源路徑:雙 \0 結尾
    TCHAR szFrom[MAX_PATH * 2] = _T("D:\\TestFolder\0\0"); 
    fos.pFrom = szFrom;
    fos.pTo = NULL; // 刪除不需目標
    
    fos.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_SILENT;
    fos.lpszProgressTitle = _T("正在刪除...");

    int nResult = SHFileOperation(&fos);
    if (nResult != 0) {
        TRACE(_T("SHFileOperation 失敗,錯誤碼: %d\n"), nResult);
        // 常見錯誤:DE_CANCELLED (使用者取消)、DE_INCOMPLETE (路徑無效)
    } else if (fos.fAnyOperationsAborted) {
        TRACE(_T("操作被使用者中斷\n"));
    } else {
        TRACE(_T("已移至回收站\n"));
    }
}

關鍵細節:pFrom 格式陷阱

  • 單一檔案:_T("C:\\Test.txt\0\0")
  • 多檔案:_T("C:\\A.txt\0C:\\B.txt\0\0")
  • 目錄:_T("C:\\Folder\0\0") (會連同內容一起刪除)
  • 必須使用雙 \0 結尾,否則函數會讀取記憶體垃圾導致崩潰或誤刪
  • 支援通配符:_T("C:\\Logs\\*.log\0\0")

進階:取得實際操作檔案清單

fos.fFlags |= FOF_WANTMAPPINGHANDLE;
// 執行後...
if (fos.hNameMappings) {
    SHNAMEMAPPING* pMap = (SHNAMEMAPPING*)fos.hNameMappings;
    for (int i = 0; i < pMap->cItems; ++i) {
        TRACE(_T("原路徑: %s -> 新路徑: %s\n"), pMap->pszOldPath, pMap->pszNewPath);
    }
    SHFreeNameMappings(fos.hNameMappings); // 必須釋放
}

適用場景與限制

場景建議
使用者手動刪除文檔/圖片必須用 FO_DELETE + FOF_ALLOWUNDO
快取/臨時檔案清理可用 CFile::Remove 或 SHFileOperation + FOF_NOCONFIRMATION + FOF_SILENT
大量檔案批次刪除SHFileOperation 效能較好,自動處理長路徑、權限、進度 UI
網路磁碟機刪除視伺服器支援,可能無回收站功能,需測試
需永久刪除 (安全清除)不可用此 API,需多次覆寫資料或呼叫 SHFileOperation 後再清空回收站

總結

SHFileOperation 是 Windows Shell 級檔案操作 API,單一呼叫即可實現「移至回收站」且完美整合系統 UI、權限、長路徑、網路路徑。記住 pFrom 雙 \0 結尾 與 FOF_ALLOWUNDO 兩大關鍵,即可為使用者提供專業、安全的刪除體驗。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved