Question

Étant donné un dossier, comment puis-je dire qu'il est un bac de recyclage? J'ai trouvé une réponse pour C ++ mais pas pour C #.

Ma première idée était de vérifier FileAttributes.System (ce qui serait une approximation acceptable dans mon cas), mais en réalité ce drapeau est effacé sur le dossier de recyclage.

solutions brutes en utilisant les noms de dossier sont hardcoded hors de question (nous sommes en 2009 après tout).

Était-ce utile?

La solution

Il y a un petit problème ici. La Corbeille Windows est un dossier virtuel et n'existe pas en réalité. Les fichiers que vous voyez ne sont pas réellement dans ce dossier, ils sont la représentation des fichiers existants sur le disque qui ont été renommés à un nom spécial, qui « supprime » eux à partir du système de fichiers visible, mais pas le physique.

Vous pouvez « preuve » par vous-même en demandant l'emplacement du dossier en utilisant l'API win32. Il retournera E_FAIL pour la Corbeille, mais pas pour d'autres dossiers (voir SHGetKnownFolderPath sur PInvoke .net ( et sur MSDN ) pour toutes les constantes que vous pouvez utiliser et les déclarations nécessaires à ce code à exécuter):

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
}

Le foldername faux "Recycle.Bin $" est répétée pour chaque lecteur. Le nom caché ne sont pas stockées dans le registre et il est accessible par l'API en tant que telle. Le KnownFolderHelper suggéré précédemment ne récupérera pas ces informations soit (le même lib a une méthode nommée pour obtenir la Corbeille, il a aussi un GetPath, il se retrouvera vide).

Mais tout est pas perdu. Ce faux non existant « nom de fichier » ou « nom du dossier » contient un fichier caché qui ressemble à quelque chose comme « S-1-5-21-2703390745-3900912742-210389625-1000 » (le vôtre sera différent). Il est l'une des deux façons « fiables » pour savoir si un certain nom de fichier est en fait un répertoire virtuel de la corbeille (l'autre manière être: supprimer un fichier par SHFileOperation , expliqué ici , et vérifier si elle apparaît dans le dossier que vous avez):

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

Note: Je ne sais pas ce que les dossiers cachés sont sur d'autres versions win32, you'l doivent expérimenter un peu. Ils ont tous le système et le jeu de drapeau caché et ressemblent à un GUID mutilée.

Les docs de l'API ne sont pas très claires à ce sujet, mais si vous avez besoin d'une confirmation, cette page explique qu'il n'y a vraiment pas de chemin qui peut être récupéré ( ancien page CSIDL connexes est beaucoup moins clair là-dessus).

Mise à jour: approches alternatives avec SHGetSpecialFolderPath , SHGetSpecialFolderLocation , ShellAPI.SHGetFolderLocation et SHGetPathFromIDList tous échouent avec le même: soit un aucun résultat ou une erreur. Je l'ai testé toutes les fonctions à la fois pour la Corbeille et pour AppData (pour être sûr que je les paramètres corrects).

Seule la documentation sur ShGetPathFromIDListEx a dit qu'il explicitement, je cite:. «à l'exception des noms d'imprimante UNC, si l'emplacement spécifié par le paramètre PIDL ne fait pas partie du système de fichiers, cette fonction échoue »

Autres conseils

code API Windows pack contient cette fonctionnalité.

Pour obtenir le dossier de la Corbeille, utilisez

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

Je ne sais pas ce que cette chaîne signifie, mais il a été inclus dans les documents que la référence à la Corbeille.

Hope this helps:)

La plupart des méthodes Corbeille liées ont été écrites en C ++ comme vous l'avez mentionné. Vous pouvez créer une classe wrapper dans votre application en utilisant extensions gérées à C ++ , alors vous devrez utiliser DLLImport comme ceci:

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

Il y a aussi des articles là-bas qui font d'une autre manière avec C #, la plupart d'entre eux utilisent PInvoke ou se fonder sur le dossier ayant $ Recycle dans son nom. Voici quelques liens que j'ai trouvé pour ce sujet

http: // sociale .msdn.microsoft.com / Forums / fr / csharpgeneral / fil / 05f1476f-a101-4766-847b-0bdf4f6ad397

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

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top