Actualmente estoy usando la siguiente función
file.Delete();
Pero, ¿cómo puedo usar esta función para enviar un archivo a la papelera de reciclaje en lugar de simplemente eliminarlo por completo?
Actualmente estoy usando la siguiente función
file.Delete();
Pero, ¿cómo puedo usar esta función para enviar un archivo a la papelera de reciclaje en lugar de simplemente eliminarlo por completo?
.NET Matters: IFileOperation in Windows Vista
y se encuentra en la Columns
carpeta.
FOFX_RECYCLEONDELETE = 0x00080000
a los indicadores de operación, y ese indicador solo es compatible con Windows 8 o superior.
Respuestas:
NOTA: Esto tampoco funciona con aplicaciones interactivas que no sean de IU como Servicios de Windows
Este contenedor puede proporcionarle la funcionalidad necesaria:
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);
}
}
Utilice FileSystem.DeleteFile y especifique la opción RecycleOption correcta .
Si bien esto funcionará con aplicaciones interactivas de IU, no funcionará con aplicaciones interactivas que no sean de IU, como una aplicación de servicio de Windows.
Microsoft.VisualBasic.FileIO.FileSystem
hace básicamente lo mismo que el ejemplo publicado aquí usando SHFileOperation
.
IL
para que no me importe. El ensamblado VB llama a la misma función WinAPI por cierto.
Microsoft.VisualBasic.Compatibility
por casualidad? Ese lo evitaría. No parece que vaya a quedar obsoleto en el corto plazo (se usa en el motor de informes RDL, etc.).
De MSDN :
Agregue una referencia al ensamblado Microsoft.VisualBasic. La clase necesaria se encuentra en esta biblioteca.
Agregue esta declaración using al principio del archivo using Microsoft.VisualBasic.FileIO
;
Úselo FileSystem.DeleteFile
para eliminar un archivo, tiene la opción de especificar papelera de reciclaje o no.
Úselo FileSystem.DeleteDirectory
para eliminar un directorio con la opción de especificar si desea enviarlo a la papelera de reciclaje o no.
La siguiente solución es más sencilla que las demás:
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")
}
}
Puede utilizar otras funcionalidades de la papelera de reciclaje utilizando esta biblioteca.
Primero, no olvide agregar la biblioteca "Microsoft Shell Controls And Automation" (desde el menú COM), para poder usar el Shell32
espacio de nombres. Se vinculará dinámicamente a su proyecto, en lugar de compilarse junto con su programa.
10
por Shell32.ShellSpecialFolderConstants.ssfBITBUCKET
. Podría valer la pena mencionar el segundo parámetro MoveHere
, con respecto a opciones como 64 ("Conservar la información de deshacer, si es posible"). Vincular algunas fuentes de documentación de MSDN sería un buen acabado.
Desafortunadamente, debe recurrir a la API de Win32 para eliminar un archivo a la Papelera de reciclaje. Pruebe el siguiente código, basado en esta publicación . Hace uso de la SHFileOperation
función genérica para las operaciones del sistema de archivos a través del Shell de Windows.
Defina lo siguiente (en una clase de utilidades probablemente sea mejor).
[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
Y para usarlo para eliminar un archivo, enviándolo a la Papelera de reciclaje, desea algo como:
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";
es incorrecta: pFrom debe tener una terminación nula doble. Debe agregar \0
el archivo shf.pFrom = "C:\\text.txt\0";
. Ver docs.microsoft.com/en-us/windows/desktop/api/shellapi/…
Puede DllImport SHFileOperation
para hacer esto.
Utilizo este método de extensión, luego puedo usar un DirectoryInfo o FileInfo y eliminarlo.
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);
}
}
una muestra de cómo llamarlo podría ser este:
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();
}
Hay una biblioteca incorporada para esto.
Primero agregue la referencia Microsoft.VisualBasic Luego agregue este código:
FileSystem.DeleteFile(path_of_the_file,
Microsoft.VisualBasic.FileIO.UIOption.AllDialogs,
Microsoft.VisualBasic.FileIO.RecycleOption.SendToRecycleBin,
Microsoft.VisualBasic.FileIO.UICancelOption.ThrowException);
He encontrado esto aquí .