Как я могу сказать, что каталог является корзиной в C#?

К вашему сведению 2,0 версии FDT были просто недавно официально выпущены, и большая работа была сделана, чтобы исправить ошибки и быть более совместимой с текущим API (полное раскрытие - я - один из специалистов по обслуживанию проекта).

проект был мертв на некоторое время, но я собираюсь попытаться сохранить его более актуальным отсюда на, таким образом, Вы могли бы просто дать ему попытку. Кроме того, мы собираемся попытаться поправиться при оценке и принятии патчей от сообщества, поэтому если Вы находите что-то, что это не работает, не стесняйтесь отправлять патч.

12
задан Community 23 May 2017 в 10:28
поделиться

3 ответа

Здесь небольшая проблема. Корзина Windows - это виртуальная папка, которая на самом деле не существует. Файлы, которые вы видите, на самом деле не находятся в этой папке, они представляют собой существующие файлы на диске, которые были переименованы в специальное имя, которое «удаляет» их из видимой файловой системы, но не из физической.

Вы можете «доказать» это сами, запросив местоположение папки с помощью Win32 API. Он вернет 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 также не будет извлекать эту информацию (та же библиотека имеет именованный метод для получения корзины, в ней также есть 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 и SHGetPath 1282] все терпят неудачу с одним и тем же: либо пустой результат, либо ошибка. Я протестировал все функции как для корзины, так и для AppData (чтобы убедиться, что я использовал правильные параметры).

7
ответ дан 2 December 2019 в 21:44
поделиться

Microsoft 's Пакет кода Windows API содержит эту функцию.

Чтобы получить папку корзины, используйте

Microsoft.WindowsAPICodePack.Shell.KnownFolderHelper.FromPath("::{645FF040-5081-101B-9F08-00AA002F954E}");

Я понятия не имею, что означает эта строка, но она была включена в документацию как ссылка на корзину.

Надеюсь, это поможет :)

3
ответ дан 2 December 2019 в 21:44
поделиться

Большинство методов, связанных с корзиной, были написаны на C ++, как вы упомянул. Вы можете создать класс-оболочку в своем приложении, используя управляемые расширения для C ++ , тогда вам придется использовать DLLImport следующим образом:

using System;
using System.Runtime.InteropServices;

class MainApp
{
[DllImport("user32.dll", EntryPoint="MessageBox")]
public static extern int MessageBox(int hWnd, String strMessage, String
strCaption, uint uiType);

public static void Main()
{
MessageBox( 0, "Hello, this is PInvoke in operation!", ".NET", 0 );
}
}

Есть также статьи, которые делают это другим способом с помощью C #, большинство из них используют PInvoke или полагаются на папку, в имени которой есть $ Recycle. Ниже приведены несколько ссылок, которые я нашел по этой теме

http://social.msdn.microsoft.com/Forums/en/csharpgeneral/thread/05f1476f-a101-4766-847b-0bdf4f6ad397

http: / /www.codeproject.com/KB/shell/recyclebin.aspx[1218 visiblehttp://www.pinvoke.net/default.aspx/shell32. SHFileOperation

2
ответ дан 2 December 2019 в 21:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: