2009-10-18 3 views
12

Bei einem Ordner, wie kann ich feststellen, dass es sich um einen Papierkorb handelt? Ich habe eine answer für C++, aber nicht für C# gefunden.Wie kann ich feststellen, dass ein Verzeichnis der Papierkorb in C# ist?

Meine erste Idee war es, nach FileAttributes.System zu suchen (was in meinem Fall eine akzeptable Annäherung wäre), aber tatsächlich wird dieses Flag im Recycle-Ordner gelöscht.

Grobe Lösungen mit fest codierten Ordnernamen kommen nicht in Frage (wir sind schließlich 2009).

+4

Können Sie die C++ - Lösung nicht einfach an C# anpassen? Wenn Sie es hier posten, können Sie auch Hilfe bekommen. Das Aufrufen von API-Funktionen aus C# ist sicherlich möglich und nicht magisch. – Joey

+0

Es ist die erste Frage in der Related Box;) Ich werde jedoch einen direkten Link hinzufügen. – mafu

+0

Natürlich würde ich eine in .NET integrierte Lösung bevorzugen, wenn möglich. – mafu

Antwort

7

Es gibt ein kleines Problem. Der Windows-Papierkorb ist ein virtueller Ordner und ist nicht vorhanden. Die Dateien, die Sie sehen, befinden sich nicht in diesem Ordner. Sie sind die Darstellung vorhandener Dateien auf der Festplatte, die in einen speziellen Namen umbenannt wurden, der sie aus dem sichtbaren Dateisystem "entfernt", aber nicht aus dem physischen.

Sie können dies selbst überprüfen, indem Sie nach dem Speicherort des Ordners mithilfe der Win32-API fragen. Es wird E_FAIL für den Papierkorb zurück, aber nicht für andere Ordner (SHGetKnownFolderPath on pinvoke.net (and on MSDN) für alle Konstanten sehen Sie und die Erklärungen, die für diesen Code ausführen können):

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 
} 

Die gefälschten folder „$ Recycle.bin " wird für jedes Laufwerk wiederholt. Der ausgeblendete Name wird nicht in der Registrierung gespeichert und auf die API kann nicht zugegriffen werden. Der früher vorgeschlagene KnownFolderHelper wird diese Information auch nicht abrufen (die gleiche Bibliothek hat eine benannte Methode, um den Papierkorb zu bekommen, sie hat auch eine GetPath, sie wird leer erscheinen).

Aber alles ist nicht verloren. Dieser gefälschte nicht existierende "Dateiname" oder "Ordnername" enthält eine versteckte Datei, die ungefähr so ​​aussieht wie "S-1-5-21-2703390745-3900912742-210389625-1000" (Ihr wird anders sein).Es ist eine von zwei "zuverlässigen" Möglichkeiten, herauszufinden, ob ein bestimmter Dateiname tatsächlich ein virtuelles Verzeichnis des Papierkorbs ist (anders ausgedrückt: Löschen Sie eine Datei über SHFileOperation, explained here, und überprüfen Sie, ob sie in dem Ordner angezeigt wird, den Sie haben):

Hinweis: Ich weiß nicht, was die versteckten Ordner auf anderen Win32-Versionen sind, müssen Sie ein wenig experimentieren. Sie alle haben das System und die versteckte Flagge gesetzt und sehen aus wie eine verstümmelte GUID.

Die API-Dokumentation ist nicht sehr klar darüber, aber wenn Sie eine Bestätigung benötigen, this page explains, dass es wirklich keinen Pfad gibt, der abgerufen werden kann (die older CSIDL related page ist viel weniger klar darüber).

Update: alternative Ansätze mit SHGetSpecialFolderPath, SHGetSpecialFolderLocation, ShellAPI.SHGetFolderLocation und SHGetPathFromIDList alle nicht mit der gleichen: entweder ein leeres Ergebnis oder einen Fehler. Ich habe alle Funktionen sowohl für den Papierkorb als auch für AppData getestet (um sicher zu sein, dass ich die richtigen Parameter verwendet habe).

Nur die Dokumentation auf ShGetPathFromIDListEx sagte, es ausdrücklich, Zitat: „Mit Ausnahme von Druckernamen UNC, wenn der Ort durch den PIDL Parameter angegeben nicht Teil des Dateisystems ist, ist diese Funktion nicht.“.

2

Die meisten Methoden für den Papierkorb wurden wie erwähnt in C++ geschrieben. Sie könnten eine Wrapper-Klasse in Ihrer Anwendung erstellen, die managed extensions to C++ verwenden, dann werden Sie DLLImport wie folgt verwenden müssen:

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

Es gibt auch Artikel gibt, die mit C# diese etwas andere Art und Weise zu tun, die meisten von ihnen verwenden PInvoke oder verlasse dich darauf, dass der Ordner $ Recycle im Namen hat. Im Folgenden sind einige Links, die ich für dieses Thema

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

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

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

2

Microsofts gefunden haben Windows API Code Pack enthält diese Funktionalität.

Um den Ordner aus dem Papierkorb zu erhalten, verwendet

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

Ich habe keine Ahnung, was das String bedeutet, aber es war in der Dokumentation als Referenz in den Papierkorb enthält.

this helps :)

+0

Diese Zeichenfolge ist eine GUID, höchstwahrscheinlich der Bezeichner für die recycelte Datei. – mgbowen

+1

Ich bin mir nicht sicher, aber ist das nicht der globale Papierkorb? Wie kann ich überprüfen, ob ein Ordner (durch den Pfad angegeben) mit diesem globalen Ordner verknüpft ist? – mafu

+0

Ich habe nicht zu tief graben, als ich meine Antwort geschrieben habe, ich hatte angenommen, dass der obige Code es relativ einfach machen würde, eine Liste von Gegenständen im Papierkorb zu bekommen. Ich werde mich heute Abend umsehen und zu dir zurückkommen müssen. –

Verwandte Themen