War es hilfreich?

Lösung

Es gibt ein kleines Problem. Der Windows-Papierkorb ist ein virtueller Ordner und existiert nicht wirklich. Die Dateien, die Sie sehen, sind nicht wirklich in diesem Ordner, sind sie die Darstellung der vorhandenen Dateien auf der Festplatte, die mit einem speziellen Namen umbenannt wurden, die „entfernt“, um sie aus dem sichtbaren Dateisystem, aber nicht die physischen.

Sie können „Beweis“ diese für sich selbst, indem für den Ordner fragen die win32-API. Es wird wieder E_FAIL für den Papierkorb, aber nicht für andere Ordner (siehe SHGetKnownFolderPath auf pinvoke .net ( und auf MSDN ) für alle Konstanten können Sie verwenden, und die für diesen Code auszuführen benötigt Erklärungen):

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. Die versteckte Name ist nicht in der Registry gespeichert, und es ist von der API als solche nicht zugänglich. Je früher vorgeschlagen KnownFolderHelper nicht abrufen diese Informationen entweder (die gleiche lib für das Erhalten des Papierkorbs eine benannte Methode hat, hat es auch eine GetPath, wird es wieder auftauchen leer).

Aber nicht alles verloren ist. Diese Fälschung nicht vorhandene „Dateiname“ oder „Ordnername“ enthält eine versteckte Datei, die wie etwas aussieht „S-1-5-21-2703390745-3900912742-210389625-1000“ (Ihr wird anders). Es ist eines von zwei „zuverlässigen“ Möglichkeiten, um herauszufinden, ob ein bestimmte Dateiname ist eigentlich ein virtuelles Verzeichnis des Papierkorbs (die andere Art und Weise zu sein: Löschen eine Datei durch SHFileOperation , erklärt hier , und prüfen, ob es in dem Ordner angezeigt Sie haben):

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

Hinweis: Ich weiß nicht, was die versteckten Ordner auf anderen win32-Versionen sind, you'l ein wenig experimentieren. Sie alle haben das System und verstecken Flag gesetzt und aussieht wie ein verstümmelten GUID.

Die API-Dokumentation ist nicht sehr klar darüber, aber wenn Sie eine Bestätigung benötigen, diese Seite erklärt , dass es wirklich keinen Weg, der (die ältere CSIDL bezogene Seite auf es viel weniger klar ist).

Update: alternative Ansätze mit SHGetSpecialFolderPath , SHGetSpecialFolderLocation , ShellAPI.SHGetFolderLocation und SHGetPathFromIDList alle mit dem gleichen fehlschlagen: entweder ein leeres Ergebnis oder ein Fehler. Getestet habe ich alle Funktionen sowohl für Papierkorb und für AppData (sicher sein verwendete ich die richtigen Parameter).

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

Andere Tipps

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

Um den Ordner aus dem Papierkorb zu erhalten, verwendet

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

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

Hope, das hilft:)

Die meisten der Papierkorb bezogenen Methoden wurden in C ++ geschrieben, wie Sie erwähnt. Sie könnten eine Wrapper-Klasse in Ihrer Anwendung erstellen, um die Verwendung von verwaltete Erweiterungen

: C ++ , dann werden Sie DLLImport wie diese 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 stützen sich auf den Ordner $ Recycle in seinem Namen hat. Im Folgenden sind ein paar Links Ich habe zu diesem Thema gefunden

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

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

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

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top