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.“.
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
Es ist die erste Frage in der Related Box;) Ich werde jedoch einen direkten Link hinzufügen. – mafu
Natürlich würde ich eine in .NET integrierte Lösung bevorzugen, wenn möglich. – mafu