将文件发送到回收站

mut*_*y91 80 c# recycle-bin

目前我正在使用以下功能

file.Delete();
Run Code Online (Sandbox Code Playgroud)

但是如何使用此功能将文件发送到回收站而不是直接删除它?

NG.*_*NG. 144

使用FileSystem.DeleteFile并指定正确的RecycleOption.

虽然这适用于UI Interactive Apps,但它不适用于非UI交互式应用程序,如Windows服务应用程序.

  • @Noldorin:丑陋,是吧?对我来说,WinAPI方式更加丑陋 - 而且,你最好还是搞砸了一些东西.我个人不喜欢VB**语法**但是在程序集中它只是`IL`所以我不介意.VB程序集调用相同的WinAPI函数btw. (17认同)
  • @noldorin这是一个非常好的解决方案,不值得一个downvote.我想参考一下为什么访问VisualBasic库是"丑陋的". (16认同)
  • @noldorin:特别是在这种情况下,`Microsoft.VisualBasic.FileIO.FileSystem`与使用`SHFileOperation`发布的示例基本相同. (7认同)
  • @Noldorin:已经过时了?你偶然错误地将程序集误认为是"Microsoft.VisualBasic.Compatibility"吗?那个我**会避免的.似乎不会很快被弃用(它在RDL报告引擎中使用,等等). (7认同)
  • @Noldorin:使用内置框架程序集看起来比将硬件映射到shell32.dll更好.使用框架组件,您可以获得可移植的更改,并获得以后的演变.映射到系统库,你有机会在任何时候过时... (6认同)
  • @Noldorin:是的,那么为什么要重写已经在框架中某处打包的东西呢? (6认同)
  • @Noldorin无论你使用什么.NET编程语言,你都知道它会使用相同的编译语言吗? (4认同)
  • 当然,因为它与Visual Basic系统绑定在一起.它甚至不打算从C#中使用,并且确实可能​​在将来的任何时候消失,而C#本身仍然完整. (3认同)
  • 工作,但不理想.在C#中通常不需要引用Microsoft.VisualBasic.在C#代码中与VB的任何关联都让我觉得难看.(虽然不是我的投票.) (2认同)
  • @DonkeyMaster:是的,已启用; 或者我如何检查它是否不在那里. (2认同)
  • 此方法似乎在内部使用SHFileOperation,它不处理长路径,并且路径长于MAX_PATH会失败(即使使用\\?\前缀). (2认同)

Eug*_*rda 50

注意:这也不适用于Windows服务等非UI交互式应用程序

这个包装器可以为您提供所需的功能:

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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

  • 如果编译为64位平台,则删除Pack = 1(否则将失败).如果没有指定Pack = 1,这将适用于32位和64位.http://pinvoke.net/default.aspx/Structures/SHFILEOPSTRUCT.html (4认同)
  • 运行此代码需要什么要求?我删除 Pack = 1 但它仍然无法编译。DllImport、DllImportAttribute、MarshalAs、MarshalAsAttribute、StructLayout、StructLayoutAttribute 不作为命名空间存在。任何帮助请谢谢:) (2认同)
  • SHFileOperation 不处理长路径,如果路径长于 MAX_PATH(即使带有 \\?\ 前缀),则会失败。 (2认同)

JLW*_*low 39

来自MSDN:

添加对Microsoft.VisualBasic程序集的引用.所需的类可在此库中找到.

将此using语句添加到文件的顶部using Microsoft.VisualBasic.FileIO;

使用FileSystem.DeleteFile删除一个文件,它指定回收站与否的选项.

使用FileSystem.DeleteDirectory删除目录的选项来指定其发送到回收站与否.

  • @rar Downvote仍然不值得,因为它没有在"由于冲突而无法引用VisualBasic库"的问题中指定.您可以在代码中轻松解决这个问题.http://stackoverflow.com/questions/1317263/system-io-versus-visualbasic-fileio (7认同)

小智 17

以下解决方案比其他解决方案简单:

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")
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以使用此库使用回收站的其他功能.

首先,不要忘记添加库"Microsoft Shell Controls And Automation"(来自COM菜单),以便能够使用Shell32命名空间.它将动态链接到您的项目,而不是与您的程序一起编译.

[1]:https://i.stack.imgur.com/erV

  • 当您专注于解决方案而不是在第一段中评论其他答案时,您的答案会更好.另外,为了清楚起见,我将`Shell32.ShellSpecialFolderConstants.ssfBITBUCKET`替换为`10`.值得一提的是"MoveHere"的第二个参数,关于像64这样的选项("如果可能的话,保留撤消信息").从MSDN链接一些文档源将是一个很好的结束. (6认同)
  • 看起来对MoveHere的调用没有表现出任何错误:在一个不存在的文件上调用它会无声地失败!它也会在比MAX_CHARS更长的路径上无声地失败,有或没有"\\?\"前缀...... (2认同)

Nol*_*rin 13

不幸的是,您需要使用Win32 API将文件删除到回收站.根据这篇文章尝试以下代码.它SHFileOperation通过Windows Shell 使用通用函数进行文件系统操作.

定义以下内容(在实用程序类中可能是最好的).

[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
Run Code Online (Sandbox Code Playgroud)

要使用它删除文件,将其发送到回收站,您需要以下内容:

var shf = new SHFILEOPSTRUCT();
shf.wFunc = FO_DELETE;
shf.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION;
shf.pFrom = @"C:\test.txt";
SHFileOperation(ref shf);
Run Code Online (Sandbox Code Playgroud)