Derzeit verwende ich die folgende Funktion
file.Delete();
Aber wie kann ich diese Funktion verwenden, um eine Datei in den Papierkorb zu senden, anstatt sie sofort zu löschen?
Derzeit verwende ich die folgende Funktion
file.Delete();
Aber wie kann ich diese Funktion verwenden, um eine Datei in den Papierkorb zu senden, anstatt sie sofort zu löschen?
.NET Matters: IFileOperation in Windows Vista
und befindet sich im Columns
Ordner.
FOFX_RECYCLEONDELETE = 0x00080000
die Operationsflags hinzufügen , und dieses Flag wird nur unter Windows 8 oder höher unterstützt.
Antworten:
HINWEIS: Dies funktioniert auch nicht mit interaktiven Nicht-UI-Apps wie Windows Services
Dieser Wrapper bietet Ihnen die erforderlichen Funktionen:
using System.Runtime.InteropServices;
public class FileOperationAPIWrapper
{
/// <summary>
/// Possible flags for the SHFileOperation method.
/// </summary>
[Flags]
public enum FileOperationFlags : ushort
{
/// <summary>
/// Do not show a dialog during the process
/// </summary>
FOF_SILENT = 0x0004,
/// <summary>
/// Do not ask the user to confirm selection
/// </summary>
FOF_NOCONFIRMATION = 0x0010,
/// <summary>
/// Delete the file to the recycle bin. (Required flag to send a file to the bin
/// </summary>
FOF_ALLOWUNDO = 0x0040,
/// <summary>
/// Do not show the names of the files or folders that are being recycled.
/// </summary>
FOF_SIMPLEPROGRESS = 0x0100,
/// <summary>
/// Surpress errors, if any occur during the process.
/// </summary>
FOF_NOERRORUI = 0x0400,
/// <summary>
/// Warn if files are too big to fit in the recycle bin and will need
/// to be deleted completely.
/// </summary>
FOF_WANTNUKEWARNING = 0x4000,
}
/// <summary>
/// File Operation Function Type for SHFileOperation
/// </summary>
public enum FileOperationType : uint
{
/// <summary>
/// Move the objects
/// </summary>
FO_MOVE = 0x0001,
/// <summary>
/// Copy the objects
/// </summary>
FO_COPY = 0x0002,
/// <summary>
/// Delete (or recycle) the objects
/// </summary>
FO_DELETE = 0x0003,
/// <summary>
/// Rename the object(s)
/// </summary>
FO_RENAME = 0x0004,
}
/// <summary>
/// SHFILEOPSTRUCT for SHFileOperation from COM
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
private struct SHFILEOPSTRUCT
{
public IntPtr hwnd;
[MarshalAs(UnmanagedType.U4)]
public FileOperationType wFunc;
public string pFrom;
public string pTo;
public FileOperationFlags fFlags;
[MarshalAs(UnmanagedType.Bool)]
public bool fAnyOperationsAborted;
public IntPtr hNameMappings;
public string lpszProgressTitle;
}
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
private static extern int SHFileOperation(ref SHFILEOPSTRUCT FileOp);
/// <summary>
/// Send file to recycle bin
/// </summary>
/// <param name="path">Location of directory or file to recycle</param>
/// <param name="flags">FileOperationFlags to add in addition to FOF_ALLOWUNDO</param>
public static bool Send(string path, FileOperationFlags flags)
{
try
{
var fs = new SHFILEOPSTRUCT
{
wFunc = FileOperationType.FO_DELETE,
pFrom = path + '\0' + '\0',
fFlags = FileOperationFlags.FOF_ALLOWUNDO | flags
};
SHFileOperation(ref fs);
return true;
}
catch (Exception)
{
return false;
}
}
/// <summary>
/// Send file to recycle bin. Display dialog, display warning if files are too big to fit (FOF_WANTNUKEWARNING)
/// </summary>
/// <param name="path">Location of directory or file to recycle</param>
public static bool Send(string path)
{
return Send(path, FileOperationFlags.FOF_NOCONFIRMATION | FileOperationFlags.FOF_WANTNUKEWARNING);
}
/// <summary>
/// Send file silently to recycle bin. Surpress dialog, surpress errors, delete if too large.
/// </summary>
/// <param name="path">Location of directory or file to recycle</param>
public static bool MoveToRecycleBin(string path)
{
return Send(path, FileOperationFlags.FOF_NOCONFIRMATION | FileOperationFlags.FOF_NOERRORUI | FileOperationFlags.FOF_SILENT);
}
private static bool deleteFile(string path, FileOperationFlags flags)
{
try
{
var fs = new SHFILEOPSTRUCT
{
wFunc = FileOperationType.FO_DELETE,
pFrom = path + '\0' + '\0',
fFlags = flags
};
SHFileOperation(ref fs);
return true;
}
catch (Exception)
{
return false;
}
}
public static bool DeleteCompletelySilent(string path)
{
return deleteFile(path,
FileOperationFlags.FOF_NOCONFIRMATION | FileOperationFlags.FOF_NOERRORUI |
FileOperationFlags.FOF_SILENT);
}
}
Verwenden Sie FileSystem.DeleteFile und geben Sie die richtige RecycleOption an .
Dies funktioniert zwar mit interaktiven UI-Apps, jedoch nicht mit interaktiven Apps ohne UI wie einer Windows-Dienst-App.
Microsoft.VisualBasic.FileIO.FileSystem
ist im Grunde das gleiche wie in dem hier geposteten Beispiel mit SHFileOperation
.
IL
mir nichts aus. Die VB-Assembly ruft übrigens dieselbe WinAPI-Funktion auf.
Microsoft.VisualBasic.Compatibility
zufällig verwechselt ? Das würde ich vermeiden. Es scheint nicht so, als würde es bald veraltet sein (es wird in der RDL-Berichts-Engine usw. verwendet).
Von MSDN :
Fügen Sie einen Verweis auf die Microsoft.VisualBasic-Assembly hinzu. Die benötigte Klasse befindet sich in dieser Bibliothek.
Fügen Sie diese using-Anweisung oben in die Datei ein using Microsoft.VisualBasic.FileIO
.
Verwenden Sie FileSystem.DeleteFile
eine Datei zu löschen, hat es die Option Papierkorb zu spezifizieren oder nicht.
Verwenden Sie FileSystem.DeleteDirectory
diese Option, um ein Verzeichnis mit der Option zu löschen, dass es an den Papierkorb gesendet werden soll oder nicht.
Die folgende Lösung ist einfacher als die anderen:
using Shell32;
static class Program
{
public static Shell shell = new Shell();
public static Folder RecyclingBin = shell.NameSpace(10);
static void Main()
{
RecyclingBin.MoveHere("PATH TO FILE/FOLDER")
}
}
Mit dieser Bibliothek können Sie andere Funktionen des Papierkorbs verwenden.
Vergessen Sie zunächst nicht, die Bibliothek "Microsoft Shell Controls And Automation" (aus dem COM-Menü) hinzuzufügen, um den Shell32
Namespace verwenden zu können. Es wird dynamisch mit Ihrem Projekt verknüpft, anstatt zusammen mit Ihrem Programm kompiliert zu werden.
10
durch Shell32.ShellSpecialFolderConstants.ssfBITBUCKET
. Es kann erwähnenswert sein, den zweiten Parameter in MoveHere
Bezug auf Optionen wie 64 zu erwähnen ("Informationen rückgängig machen, wenn möglich"). Das Verknüpfen einiger Dokumentationsquellen von MSDN wäre ein guter Abschluss.
Leider müssen Sie auf die Win32-API zurückgreifen, um eine Datei aus dem Papierkorb zu entfernen. Versuchen Sie den folgenden Code, der auf diesem Beitrag basiert . Es nutzt die generische SHFileOperation
Funktion für Dateisystemoperationen über die Windows-Shell.
Definieren Sie Folgendes (in einer Utilities-Klasse ist dies wahrscheinlich am besten).
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto, Pack=1)]
public struct SHFILEOPSTRUCT
{
public IntPtr hwnd;
[MarshalAs(UnmanagedType.U4)] public int wFunc;
public string pFrom;
public string pTo;
public short fFlags;
[MarshalAs(UnmanagedType.Bool)] public bool fAnyOperationsAborted;
public IntPtr hNameMappings;
public string lpszProgressTitle;
}
[DllImport("shell32.dll", CharSet=CharSet.Auto)]
public static extern int SHFileOperation(ref SHFILEOPSTRUCT FileOp);
public const int FO_DELETE = 3;
public const int FOF_ALLOWUNDO = 0x40;
public const int FOF_NOCONFIRMATION = 0x10; // Don't prompt the user
Und um damit eine Datei zu löschen und sie in den Papierkorb zu senden, möchten Sie Folgendes:
var shf = new SHFILEOPSTRUCT();
shf.wFunc = FO_DELETE;
shf.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION;
shf.pFrom = @"C:\test.txt";
SHFileOperation(ref shf);
shf.pFrom = @"C:\test.txt";
falsch ist - pFrom muss doppelt nullterminiert sein. Sie sollten \0
in der Datei hinzufügen shf.pFrom = "C:\\text.txt\0";
. Siehe docs.microsoft.com/en-us/windows/desktop/api/shellapi/…
Sie können DllImport SHFileOperation
, um dies zu tun.
Hierfür gibt es eine eingebaute Bibliothek .
Fügen Sie zuerst die Referenz Microsoft.VisualBasic hinzu. Fügen Sie dann diesen Code hinzu:
FileSystem.DeleteFile(path_of_the_file,
Microsoft.VisualBasic.FileIO.UIOption.AllDialogs,
Microsoft.VisualBasic.FileIO.RecycleOption.SendToRecycleBin,
Microsoft.VisualBasic.FileIO.UICancelOption.ThrowException);
Ich habe das hier gefunden .
Ich verwende diese Erweiterungsmethode, dann kann ich einfach eine DirectoryInfo oder FileInfo verwenden und diese löschen.
public static class NativeMethods
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct SHFILEOPSTRUCT
{
public IntPtr hwnd;
[MarshalAs(UnmanagedType.U4)]
public int wFunc;
public string pFrom;
public string pTo;
public short fFlags;
[MarshalAs(UnmanagedType.Bool)]
public bool fAnyOperationsAborted;
public IntPtr hNameMappings;
public string lpszProgressTitle;
}
private const int FO_DELETE = 0x0003;
private const int FOF_ALLOWUNDO = 0x0040; // Preserve undo information, if possible.
private const int FOF_NOCONFIRMATION = 0x0010; // Show no confirmation dialog box to the user
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
static extern int SHFileOperation(ref SHFILEOPSTRUCT FileOp);
static bool DeleteFileOrFolder(string path)
{
SHFILEOPSTRUCT fileop = new SHFILEOPSTRUCT();
fileop.wFunc = FO_DELETE;
fileop.pFrom = path + '\0' + '\0';
fileop.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION;
var rc= SHFileOperation(ref fileop);
return rc==0;
}
public static bool ToRecycleBin(this DirectoryInfo dir)
{
dir?.Refresh();
if(dir is null || !dir.Exists)
{
return false;
}
else
return DeleteFileOrFolder(dir.FullName);
}
public static bool ToRecycleBin(this FileInfo file)
{
file?.Refresh();
if(file is null ||!file.Exists)
{
return false;
}
return DeleteFileOrFolder(file.FullName);
}
}
Ein Beispiel, wie man es nennt, könnte sein:
private void BtnDelete_Click(object sender, EventArgs e)
{
if(MessageBox.Show("Are you sure you would like to delete this directory?", "Delete & Close", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
return;
var dir= new DirectoryInfo(directoryName);
dir.ToRecycleBin();
}