2009-06-01 41 views
3

我正在嘗試編寫一些簡單的代碼,它將返回本地驅動器上回收站的目錄。看起來好像很簡單 - 在Google上應該有一千個答案。還沒有找到一個:(在本地NTFS驅動器上查找回收站

我發現FAT和NTFS驅動器有不同的基本名稱(RECYCLED和RECYCLER)。我發現'回收站'是一個虛擬文件夾,結合了回收站所有驅動器在機器上

我沒有找到的是找到C:驅動器的回收站目錄 - 即使在越南語(或任何其他非英語)機器上的方法。無論是「RECYCLER」被國際化與否)

任何人都可以點我一個明確的答案?

感謝

更新:意識到CSIDL_BITBUCKET和使用它的功能。從我讀過的所有內容中,它指向一個虛擬目錄,該目錄是該用戶在所有驅動器上刪除的所有文件的聯合。尋找物理回收站目錄(在我的Vista上,它似乎是C:\ $ Recycle.Bin,據我所知)

+0

參見[這個問題](http://stackoverflow.com/questions/37053/how-can-i-get-the-localized-name-of-a -special-windows-folder-recycle-bin-etc)和[this one](http://stackoverflow.com/questions/94046/how-can-i-tell-that-a-directory-is-really-a -recycle-bin)。 – 2009-06-01 20:03:57

+0

看着你的第一個鏈接引用的文章。它只是引用CSIDL_BITBUCKET,它引用整個機器的用戶的虛擬回收站目錄,而不是每個驅動器目錄。這是我在Google上可以找到的所有內容的問題 - 它都指向這個虛擬目錄。 – DougN 2009-06-02 02:06:28

+0

哦,第二篇文章強制你瀏覽所有的目錄,尋找一個與回收站的GUID相匹配的目錄。沒有辦法讓每個驅動器的回收站的基礎? – DougN 2009-06-02 02:07:18

回答

2

使用Raymond Chen的建議和其他人的技巧(不記得我在哪裏找到它)我提供了一個函數,可以在驅動器上找到回收站目錄。該函數循環遍歷根目錄中的目錄查看隱藏和/或系統目錄。當它找到一個時,它會檢查子查找具有CLSID_Recycle Bin的子目錄。

請注意,我在下面包含了兩個GetFolderCLSID函數。雷蒙德陳是更簡單的,但它不適用於Windows 2000.其他實現更長,但似乎無處不在。

調用方式如下:CString recycleDir = FindRecycleBinOnDrive(L「C:\」);

CString FindRecycleBinOnDrive(LPCWSTR path) 
{ 
    CString search; 
    search.Format(L"%c:\\*", path[0]); 
    WIN32_FIND_DATA fd = {0}; 
    HANDLE fHandle = FindFirstFile(search, &fd); 
    while(INVALID_HANDLE_VALUE != fHandle) 
    { 
     if(FILE_ATTRIBUTE_DIRECTORY == (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) //only check directories 
     { 
      if(0 != (fd.dwFileAttributes & (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) //only check hidden and/or system directories 
      { 
       //the recycle bin directory itself won't be marked, but a SID-specific child directory will, so now look at them 
       CString childSearch; 
       childSearch.Format(L"%c:\\%s\\*", path[0], fd.cFileName); 
       WIN32_FIND_DATA childFD = {0}; 
       HANDLE childHandle = FindFirstFile(childSearch, &childFD); 
       while(INVALID_HANDLE_VALUE != childHandle) 
       { 
        if((FILE_ATTRIBUTE_DIRECTORY == (childFD.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) && //only check directories 
         (childFD.cFileName[0] != L'.')) //don't check . and .. dirs 
        { 
         CString fullPath; 
         fullPath.Format(L"%c:\\%s\\%s", path[0], fd.cFileName, childFD.cFileName); 
         CLSID id = {0}; 
         HRESULT hr = GetFolderCLSID(fullPath, id); 
         if(SUCCEEDED(hr)) 
         { 
          if(IsEqualGUID(CLSID_RecycleBin, id)) 
          { 
           FindClose(childHandle); 
           FindClose(fHandle); 
           //return the parent (recycle bin) directory 
           fullPath.Format(L"%c:\\%s", path[0], fd.cFileName); 
           return fullPath; 
          } 
         } 
         else 
         { 
          Log(logERROR, L"GetFolderCLSID returned %08X for %s", hr, fullPath); 
         } 
        } 

        if(FALSE == FindNextFile(childHandle, &childFD)) 
        { 
         FindClose(childHandle); 
         childHandle = INVALID_HANDLE_VALUE; 
        } 
       } 
      } 
     } 
     if(FALSE == FindNextFile(fHandle, &fd)) 
     { 
      FindClose(fHandle); 
      fHandle = INVALID_HANDLE_VALUE; 
     } 
    } 
    _ASSERT(0); 
    return L""; 
} 


//Works on Windows 2000, and even as Local System account 
HRESULT GetFolderCLSID(LPCWSTR path, CLSID& pathCLSID) 
{ 
    LPMALLOC pMalloc = NULL; 
    HRESULT hr = 0; 
    if (SUCCEEDED(hr = SHGetMalloc(&pMalloc))) 
    { 
     LPSHELLFOLDER pshfDesktop = NULL; 
     if (SUCCEEDED(hr = SHGetDesktopFolder(&pshfDesktop))) 
     { 
      LPITEMIDLIST pidl = NULL; 
      DWORD dwAttributes = SFGAO_FOLDER; 
      if (SUCCEEDED(hr = pshfDesktop->ParseDisplayName(NULL, NULL, (LPWSTR)path, NULL, &pidl, &dwAttributes))) 
      { 
       LPPERSIST pPersist = NULL; 
       if (SUCCEEDED(hr = pshfDesktop->BindToObject(pidl, NULL, IID_IPersist, (LPVOID *) &pPersist))) 
       { 
        hr = pPersist->GetClassID(&pathCLSID); 
        pPersist->Release(); 
       } 
       pMalloc->Free(pidl); 
      } 
      pshfDesktop->Release(); 
     } 
     pMalloc->Release(); 
    } 
    return hr; 
} 


//Not supported on Windows 2000 since SHParseDisplayName wasn't implemented then 
//HRESULT GetFolderCLSID(LPCWSTR pszPath, CLSID& pathCLSID) 
//{ 
// SHDESCRIPTIONID did = {0}; 
// HRESULT hr = 0; 
// LPITEMIDLIST pidl = NULL; 
// if (SUCCEEDED(hr = SHParseDisplayName(pszPath, NULL, &pidl, 0, NULL))) //not supported by Windows 2000 
// { 
//  IShellFolder *psf = NULL; 
//  LPCITEMIDLIST pidlChild = NULL; 
//  if (SUCCEEDED(hr = SHBindToParent(pidl, IID_IShellFolder, (void**)&psf, &pidlChild))) 
//  { 
//   hr = SHGetDataFromIDList(psf, pidlChild, SHGDFIL_DESCRIPTIONID, &did, sizeof(did)); 
//   psf->Release(); 
//   pathCLSID = did.clsid; 
//  } 
//  CoTaskMemFree(pidl); 
// } 
// return hr; 
//} 
0

在Win32中,使用SHGetSpecialFolderLocation。通過CSIDL_BITBUCKET作爲CDIL參數。

+0

CSIDL_BITBUCKET是虛擬的。如果指定了虛擬文件夾,則此功能將失敗。 – 2009-06-01 19:57:34

1

有點晚,但也許遲到總比不到好...

調試SHELL32.DLL後,我發現,每個Windows版本的循環路徑是硬編碼,並且還取決於在該驅動器的文件系統上。我已經在Windows XP,Vista和Windows7的測試這樣的:

設X:是我們想要得到的路徑回收站的驅動器,讓SID是當前用戶的SID,則:

 

    switchif(OsType) { 
     case WindowsXP: 
     { 
      if(PartitionType("X:") == NTFS) 
      { 
       printf("Path is: X:\\Recycler\\SID\\"); 
      } 
      else 
      { 
       printf("Path is X:\\RECYCLED\\"); 
      } 
     } 

     case WindowsVista: 
     case Windows7: 
     { 
      if(PartitionType("X:") == NTFS) 
      { 
       printf("Path is: X:\\$Recycle.bin\\SID\\"); 
      } 
      else 
      { 
       printf("Path is X:\\$RECYCLE.BIN\\"); 
      } 
     } 
    } 
 

維基文章提出了同樣的事實: http://en.wikipedia.org/wiki/Recycle_Bin_%28Windows%29

相關問題