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;
//}
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. –
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
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