Question

Je suis en train d'écrire un code simple qui renverra le répertoire pour la corbeille sur un disque local. On dirait que ce serait simple - devrait être un millier de réponses sur Google. Vous n'avez pas encore trouvé: (

J'ai trouvé que les lecteurs FAT et NTFS ont des noms de base (et recycleur) RECYCLE. J'ai trouvé que « la » corbeille est un dossier virtuel qui combine les bacs de recyclage de tous les lecteurs sur la machine.

Ce que je ne l'ai pas trouvé un moyen de trouver le lecteur C: répertoire corbeille de - même sur un Vietnamien (ou tout autre non-anglais) machine. (Pas de message que je peux trouver indiquer si « RECYCLER » s'internationalisé ou non)

Quelqu'un peut-il me indiquer une réponse définitive?

Merci

MISE À JOUR: Conscient de CSIDL_BITBUCKET et les fonctions qui l'utilisent. De tout ce que j'ai lu cependant, il pointe vers un répertoire virtuel qui est l'union de tous les fichiers supprimés par l'utilisateur sur tous les lecteurs. Vous recherchez le répertoire bin de recyclage physique (sur mon Vista, il semble être C: \ $ Recycle.Bin pour autant que je peux dire)

Était-ce utile?

La solution 2

En utilisant les conseils de Raymond Chen, et quelqu'un d'autre la technique (ne me souviens pas où je l'ai trouvé) je présente une fonction qui va trouver le répertoire Corbeille sur un lecteur. Les cycles de fonction à travers les répertoires dans le répertoire racine regardant cachés et / ou répertoires système. Quand il en trouve un, il vérifie les sous-répertoires de l'enfant à la recherche d'un qui a CLSID_Recycle Bin.

Notez que j'ai inclus deux fonctions GetFolderCLSID ci-dessous. Raymond Chen est le plus simple, mais il ne fonctionne pas sur Windows 2000. L'autre mise en œuvre est plus longue, mais semble fonctionner partout.

Appel comme: 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;
//}

Autres conseils

Un peu en retard, mais peut-être mieux vaut tard que jamais ...

Après le débogage shell32.dll, j'ai trouvé que pour chaque version de Windows la voie de recyclage est hardcoded et, aussi, dépend du système de fichiers de ce lecteur. Je l'ai testé sur Windows XP, Vista et Windows7:

Soit X: soit le lecteur que nous voulons obtenir le chemin de la corbeille et laissez SID être le SID de l'utilisateur actuel, puis:


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

Un article wiki présente les mêmes faits: http://en.wikipedia.org/wiki/Recycle_Bin_%28Windows%29

Dans Win32, utilisez SHGetSpecialFolderLocation . Passer CSIDL_BITBUCKET comme paramètre CDIL.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top