로컬 NTFS 드라이브에서 재활용 빈을 찾습니다
-
06-09-2019 - |
문제
로컬 드라이브에서 재활용 빈의 디렉토리를 반환 할 간단한 코드를 작성하려고합니다. 간단한 것 같습니다. Google에서 수천 개의 답변이되어야합니다. 아직 찾지 못했습니다 :(
나는 지방과 NTF 드라이브가 다른 기본 이름 (재활용 및 재활용기)을 가지고 있음을 발견했습니다. ''재활용 빈은 기계의 모든 드라이브의 재활용 쓰레기통을 결합한 가상 폴더라는 것을 알았습니다.
내가 찾지 못한 것은 베트남 (또는 다른 비 영어) 기계에서도 C : Drive의 재활용 빈 디렉토리를 찾는 방법입니다. (내가 찾을 수있는 게시물 없음 "Recycler"가 국제화되는지 여부를 나타냅니다)
누구든지 나를 결정적인 대답을 지적 할 수 있습니까?
감사
업데이트 : 알고 있습니다 CSIDL_BITBUCKET
그리고 그것을 사용하는 기능. 그래도 내가 읽은 모든 것에서 가상 모든 드라이브에서 해당 사용자가 삭제 된 모든 파일의 통합 인 디렉토리. 물리적 재활용 빈 디렉토리를 찾고 있습니다 (내 Vista에서는 내가 알 수있는 한 C : $ recycle.bin으로 보입니다)
해결책 2
Raymond Chen의 조언과 다른 사람의 기술을 사용하여 (어디에서 찾았는지 기억할 수 없음) 드라이브에서 재활용 빈 디렉토리를 찾을 수있는 기능을 제시합니다. 이 기능은 숨겨진 및/또는 시스템 디렉토리를보고있는 루트 디렉토리의 디렉토리를 통해 순환합니다. 하나를 찾으면 CLSID_RECYCLE BIN이있는 아동 하위 디렉토리를 확인합니다.
아래에 두 개의 getfolderclsid 함수를 포함 시켰습니다. Raymond Chen 's는 더 간단하지만 Windows 2000에서는 작동하지 않습니다. 다른 구현은 더 길지만 어디에서나 작동하는 것으로 보입니다.
Call Like : 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;
//}
다른 팁
Raymond Chen은 답이 있습니다. 디렉토리가 실제로 재활용 빈이라고 말하는 방법?
조금 늦었지만 결코 늦지 않는 것보다 늦었을 것입니다 ...
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
Win32에서 사용하십시오 ShgetSpecialfolderlocation. 통과하다 csidl_bitbucket CDIL 매개 변수로.