2009-06-01 5 views
3

Ich versuche, einen einfachen Code zu schreiben, der das Verzeichnis für den Papierkorb auf einem lokalen Laufwerk zurückgibt. Es scheint, als wäre es einfach - sollte tausend Antworten auf Google sein. Ich habe noch keine gefunden :(Den Papierkorb auf einem lokalen NTFS-Laufwerk finden

Ich habe festgestellt, dass FAT und NTFS-Laufwerke verschiedene Basisnamen haben (RECYCLED und RECYCLER). Ich habe festgestellt, dass "der" Papierkorb ist ein virtueller Ordner, der die Papierkörbe kombiniert Alle Laufwerke auf der Maschine

Was ich nicht gefunden habe, ist eine Möglichkeit, das Papierkorbverzeichnis von C: drive zu finden - sogar auf einem vietnamesischen (oder einem anderen nicht englischsprachigen) Rechner. (Keine Posts, die ich finden kann ob „Recycler“ wird internationalisiert oder nicht)

mir jemand auf eine endgültige Antwort darauf kann?

Dank

UPDATE: Aware von CSIDL_BITBUCKET und die Funktionen, die es verwenden. Von allem, was ich gelesen habe, zeigt es auf ein virtuelles Verzeichnis, das die Vereinigung aller gelöschten Dateien durch diesen Benutzer auf allen Laufwerken ist. Suche nach dem physischen Papierkorbverzeichnis (auf meinem Vista scheint es C: \ $ Recycle.Bin zu sein, soweit ich das beurteilen kann)

+0

See [diese Frage] (http://stackoverflow.com/questions/37053/how-can-i-get-the-localized-name-of-a -special-windows-folder-recycle-bin-etc) und [diese] (http://stackoverflow.com/questions/94046/how-can-i-tell-that-a-directory-isreally-a -Recycle-Bin) auch. –

+0

Blick auf den Artikel von Ihrem ersten Link verwiesen. Es verweist einfach auf CSIDL_BITBUCKET, das sich auf das virtuelle Papierkorbverzeichnis des Benutzers für die gesamte Maschine bezieht, nicht auf ein Verzeichnis pro Laufwerk.Dies ist das Problem mit allem, was ich bei Google finden kann - es zeigt alles auf dieses virtuelle Verzeichnis. – DougN

+0

Oh, und der zweite Post zwingt Sie, durch alle Verzeichnisse zu gehen, die nach einer Suche suchen, die der GUID des Papierkorbs entspricht. Gibt es keine Möglichkeit, den Papierkorb pro Laufwerk zu erhalten? – DougN

Antwort

2

Mit dem Rat von Raymond Chen und der Technik von jemand anderem (ich kann mich nicht erinnern, wo ich es gefunden habe) stelle ich eine Funktion vor, die den Papierkorb auf einem Laufwerk findet. Die Funktion durchläuft die Verzeichnisse im Stammverzeichnis und sucht nach versteckten und/oder Systemverzeichnissen. Wenn es einen findet, überprüft es die untergeordneten Unterverzeichnisse nach einem mit CLSID_Recycle Bin.

Beachten Sie, dass ich zwei GetFolderCLSID-Funktionen unten aufgeführt habe. Raymond Chens ist der einfachere, aber unter Windows 2000 funktioniert es nicht. Die andere Implementierung ist länger, scheint aber überall zu funktionieren.

Aufruf wie: 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

Verwenden Sie in Win32 SHGetSpecialFolderLocation. Übergeben Sie CSIDL_BITBUCKET als den CDIL-Parameter.

+0

CSIDL_BITBUCKET ist virtuell. Wenn ein virtueller Ordner angegeben wird, schlägt diese Funktion fehl. –

+0

Richtig du bist. SHGetSpecialFolderLocation ist was Sie für den Recycler wollen. Die Antwort wurde aktualisiert. –

+1

Von meinem Lesevorgang gibt SHGetSpecialFolderLocation den virtuellen Benutzerordner zurück - den Ordner mit allen lokalen Laufwerken in einem. Ich suche nach dem physischen Papierkorbverzeichnis auf der Festplatte. – DougN

1
+0

Ich fange an zu denken, dass dies der einzige Weg sein könnte - durchlaufen Sie alle Verzeichnisse im Wurzelverzeichnis und überprüfen Sie jedes mit Raymonds Methode, die Verzeichnis-GUID mit der Papierkorb-GUID zu vergleichen. Sie würden denken, dass es einen direkteren Weg geben würde ... – DougN

+1

Microsoft wahrscheinlich nicht wollen, dass Sie mit diesen Ordnern direkt durcheinander bringen, weil sie in der Zukunft möglicherweise geändert werden. –

1

Ein wenig spät, aber vielleicht besser spät als nie ...

Nach shell32.dll Debuggen, ich habe, dass der Rückführweg hartcodiert von Fenstern für jede Version zu finden ist, und auch, abhängig auf dem Dateisystem dieses Laufwerks. Ich habe dies auf Windows XP, Vista und Windows7 getestet:

Sei X: das Laufwerk wir den Weg in den Papierkorb bekommen und lassen SID das SID des aktuellen Benutzers sein, dann gilt:

 

    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\\"); 
      } 
     } 
    } 
 

Ein Wiki Artikel stellt die gleichen Fakten: http://en.wikipedia.org/wiki/Recycle_Bin_%28Windows%29

+0

Das ist interessant. Frage mich, ob es auch in fremdsprachigen Versionen von Windows hält? – DougN

+0

Ich glaube es tut. – botismarius

Verwandte Themen