2012-08-28 40 views
2

失敗,我使用下面的函數來刪除文件到回收站:(C++,MFC,Unicode)的SHFileOperation FOF_ALLOWUNDO上的長文件名

bool DeleteFileToPaperbasket (CString filename) 
{ 
    TCHAR Buffer[2048+4]; 

    _tcsncpy_s (Buffer, 2048+4, filename, 2048); 
    Buffer[_tcslen(Buffer)+1]=0; //Double-Null-Termination 

    SHFILEOPSTRUCT s; 
    s.hwnd     = NULL; 
    s.wFunc     = FO_DELETE; 
    s.pFrom     = Buffer; 
    s.pTo     = NULL; 
    s.fFlags    = FOF_ALLOWUNDO | FOF_SILENT | FOF_NOERRORUI; 
    s.fAnyOperationsAborted = false; 
    s.hNameMappings   = NULL; 
    s.lpszProgressTitle  = NULL; 

    int rc = SHFileOperation(&s); 

    return (rc==0); 
} 

這很好地工作對於大多數文件。但是,如果path + filename超過255個字符(並且仍然比2048個字符短得多),SHFileOperation返回124.這是DE_INVALIDFILES。

但是怎麼了?我檢查了一百萬次。路徑是雙空終止的,我沒有使用\\?\並且它適用於短文件名。

我完全沒了主意......

回答

3

我認爲向後的可比性正在以幾種方式咬你 - 而且我需要真正看到你使用的路徑並實現一些錯誤檢查代碼來提供幫助。但這裏有一些提示。

  1. 您不會得到DE_INVALIDFILES 0x7C「源或目標中的路徑或兩者都無效。」對於最大路徑違規,您將得到DE_PATHTOODEEP 0x79「源或目標路徑超出或超出MAX_PATH。」

  2. 這些錯誤代碼(返回值)做的,就可以了,隨時間而變化,以確保您的特定錯誤代碼是什麼意思,你需要GetLastError function(msdn)

  3. 此外,從SHFileOperation function documentation採取檢查:「如果你沒有檢查fAnyOperationsAborted和返回值,你就不知道該函數完成了你所要求的全部任務,而且你可能會在不正確的假設下進行。」

  4. 你不應該使用這個API非常長的路徑名,它已經在Vista取代+通過IFileOperation interface

  5. 爲什麼它可以在資源管理器中工作,而不是通過這個LEGACY API是解釋 - 從MSDN頁採取 Naming Files, Paths, and Namespaces

外殼和文件系統有不同的要求。它可能是 使用Windows API創建的路徑,shell用戶 接口無法正確解釋。

希望這是有幫助的

+0

謝謝,是的,這很有幫助。我試過了IFileOperation :: DeleteFile。採取一些包裝代碼來執行管理,但它的工作原理!謝謝! – user178379

+0

爲了您的觀點2 - 從SHFileOperation函數文檔:'不要使用GetLastError與此函數的返回值.' –

0

回收站不支持的文件其路徑的長度超過MAX_PATH。您可以通過嘗試在資源管理器中回收這樣的文件來驗證這一點 - 您將收到有關路徑過長的錯誤消息。

+1

謝謝,但我已經試過了。用Windows資源管理器刪除(並恢復)這樣的文件確實有效。 (Windows 7) - 但你說得對,Windows仍然有限制。如果我嘗試使用資源管理器複製並粘貼(=重複)該文件,則出現錯誤。 – user178379