¿Cómo puedo saber que es un directorio de la papelera de reciclaje en C #?

StackOverflow https://stackoverflow.com/questions/1585295

  •  22-09-2019
  •  | 
  •  
¿Fue útil?

Solución

Hay un pequeño problema. La papelera de reciclaje es una carpeta virtual y en realidad no existe. Los archivos que se ve no son en realidad en esa carpeta, que son la representación de los archivos existentes en el disco que se han cambiado el nombre a un nombre especial, que "quita" ellos desde el sistema de archivos visibles, pero no el físico.

Puede "prueba" de esto por sí mismo al pedir la ubicación de la carpeta con la API de Win32. Se volverá E_FAIL de la papelera de reciclaje, pero no para otras carpetas (ver SHGetKnownFolderPath en PInvoke .net ( y en MSDN ) para todas las constantes que puede utilizar y las declaraciones necesarias para que este código de ejecución):

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
}

El nombre de carpeta falsa "$ Recycle.bin" se repite para cada unidad. El nombre oculto no se almacena en el registro y no es accesible por la API como tal. El KnownFolderHelper sugirió anteriormente no recuperará esta información ya sea (el mismo lib tiene un método llamado para conseguir la papelera de reciclaje, sino que también tiene un GetPath, que a su vez a vacío).

Sin embargo, no todo está perdido. Este falso "nombre de archivo" o "nombre de carpeta" no-existente contiene un archivo oculto que se ve algo como "S-1-5-21-2703390745-3900912742-210389625-1000" (el suyo será diferente). una de dos maneras "fiables" Es para saber si un determinado nombre de archivo es en realidad un directorio virtual de la papelera de reciclaje (la otra manera de ser: borrar un archivo a través de SHFileOperation , explicados aquí , y comprobar si aparece en la carpeta que tiene):

string [] entries = Directory.GetFileSystemEntries(@"c:\$Recycle.bin", "?-?-?-??*");
if(entries.Length > 0)
   // we have a winner
else 
   // no, not the recycle bin

Nota: no sé lo que las carpetas ocultas están en otras versiones de Win32, te tienen que experimentar un poco. Todos ellos tienen el sistema y conjunto del indicador oculta y se ven como un GUID destrozado.

Los documentos de la API no son muy claras al respecto, pero si necesita confirmación, esta página explica que en realidad hay un camino que se puede recuperar (el página relacionada CSIDL anterior es mucho menos claro en él).

Actualización: enfoques alternativos con SHGetSpecialFolderPath , SHGetSpecialFolderLocation , ShellAPI.SHGetFolderLocation y SHGetPathFromIDList todos fallan con el mismo: o bien una resultado vacío o un error. Probé todas las funciones tanto para la papelera de reciclaje y para datos de programa (para estar seguro utilicé los parámetros correctos).

Sólo la documentación sobre ShGetPathFromIDListEx dijo que explícitamente, cita:. "a excepción de los nombres de impresora UNC, si la ubicación especificada por el parámetro pidl no es parte del sistema de archivos, esta función no"

Otros consejos

Código paquete de API de Windows de Microsoft contiene esta funcionalidad.

Para obtener la carpeta de la papelera de reciclaje, el uso

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

No tengo idea de lo que eso significa cuerda, pero se incluyó en la documentación como la referencia a la papelera de reciclaje.

Espero que esto ayude:)

La mayoría de los métodos relacionados con la papelera de reciclaje se han escrito en C ++ como usted ha mencionado. Se puede crear una clase contenedora en su aplicación utilizando las extensiones administrados a C ++ , entonces usted tendrá que utilizar DLLImport como esto:

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

También hay artículos por ahí que hacen esto de alguna otra manera con C #, la mayoría de ellos utilizan PInvoke o confiar en la carpeta que tiene $ reciclaje en su nombre. A continuación se presentan algunos enlaces que he encontrado para este tema

http: // sociales .msdn.microsoft.com / foros / en / csharpgeneral / hilo / 05f1476f-a101-4766-847b-0bdf4f6ad397

http://www.codeproject.com/KB/shell/recyclebin.aspx

http://www.pinvoke.net/default.aspx/shell32.SHFileOperation

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top