Ответ 1
Здесь есть небольшая проблема. Корзина Windows является виртуальной папкой и фактически не существует. Файлы, которые вы видите, фактически не находятся в этой папке, они представляют собой существующие файлы на диске, которые были переименованы в специальное имя, которое "удаляет" их из видимой файловой системы, но не физическое.
Вы можете "подтвердить" это для себя, запросив местоположение папки, используя API win32. Он вернет E_FAIL
для корзины, но не для других папок (см. SHGetKnownFolderPath на pinvoke.net (и в MSDN) для всех констант, которые вы можете использовать, и деклараций, необходимых для запуска этого кода):
IntPtr ptrRecycleBinPath;
// try it with KnownFolder.QuickLaunch to see it working:
HRESULT hr = (HRESULT) SHGetKnownFolderPath(
KnownFolder.RecycleBinFolder,
0,
IntPtr.Zero,
out ptrRecycleBinPath);
if (hr == HRESULT.E_FAIL)
{
Console.WriteLine("No folder avaialable, virtual folder");
}
else if (hr == HRESULT.S_OK)
{
string RecycleBinPath = Marshal.PtrToStringUni(ptrRecycleBinPath);
Marshal.FreeCoTaskMem(ptrRecycleBinPath);
Console.WriteLine("path: " + RecycleBinPath);
}
// for convenience, you can use the code above
// directly if you paste the follow declarations in your class:
// get a "known path"
[DllImport("shell32.dll")]
static extern long SHGetKnownFolderPath(
[MarshalAs(UnmanagedType.LPStruct)] Guid rfid,
uint dwFlags,
IntPtr hToken,
out IntPtr pszPath);
// known folder GUID declarations
public static class KnownFolder
{
// many more entries exist, left out for clarity here
public static readonly Guid RecycleBinFolder =
new Guid("B7534046-3ECB-4C18-BE4E-64CD4CB7D6AC");
public static readonly Guid QuickLaunch =
new Guid("52a4f021-7b75-48a9-9f6b-4b87a210bc8f");
//....
}
// results of COM invocations:
enum HRESULT : uint
{
S_FALSE = 0x0001,
S_OK = 0x0000,
E_FAIL = 0x80004005,
E_INVALIDARG = 0x80070057,
E_OUTOFMEMORY = 0x8007000E
}
Поддельное имя папки "$ Recycle.bin" повторяется для каждого диска. Скрытое имя не сохраняется в реестре и недоступно API как таковой. Ранее предложенный KnownFolderHelper не получит эту информацию (тот же lib имеет именованный метод для получения Корзины, он также имеет GetPath
, он будет пустым).
Но все не потеряно. Это поддельное несуществующее "имя файла" или "имя папки" содержит скрытый файл, который выглядит примерно так: "S-1-5-21-2703390745-3900912742-210389625-1000" (ваш будет другим). Это один из двух "надежных" способов выяснить, является ли определенное имя файла виртуальным каталогом корзины (другим способом является: удаление файла через SHFileOperation
, объясняется здесь и проверьте, отображается ли она в вашей папке):
string [] entries = Directory.GetFileSystemEntries(@"c:\$Recycle.bin", "?-?-?-??*");
if(entries.Length > 0)
// we have a winner
else
// no, not the recycle bin
Примечание. Я не знаю, что скрытые папки находятся на других версиях win32, вам придется немного поэкспериментировать. Все они имеют систему и скрытый флаг и выглядят как искаженный GUID.
Документы API не очень понятны, но если вам нужно подтверждение, эта страница объясняет, что на самом деле нет пути, который может быть (более ранняя страница, связанная с CSIDL, на нем гораздо менее понятна).
Обновить: альтернативные подходы с SHGetSpecialFolderPath
, SHGetSpecialFolderLocation
, ShellAPI.SHGetFolderLocation
и SHGetPathFromIDList
все сбой: с пустым результатом или с ошибкой, Я протестировал все функции как для корзины, так и для AppData (чтобы убедиться, что я использовал правильные параметры).
Только документация на ShGetPathFromIDListEx
явно указала на нее: "За исключением имен принтеров UNC, если местоположение, указанное параметром pidl не является частью файловой системы, эта функция не работает.".