删除文件回收站在Windows x64在C#

问题描述:

我有这个类似乎在非64位工作得很好。删除文件回收站在Windows x64在C#

using System; 
using System.Runtime.InteropServices; 

namespace DeleteToRecycleBin 
{ 
/// <summary> 
/// Send files directly to the recycle bin. 
/// </summary> 
public class RecybleBin 
{ 

    /// <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, Pack = 1)] 
    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 readonly bool fAnyOperationsAborted; 
     public readonly IntPtr hNameMappings; 
     public readonly 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 
     { 
      SHFILEOPSTRUCT fs = new SHFILEOPSTRUCT 
            { 
             wFunc = FileOperationType.FO_DELETE, 
             pFrom = path + '\0' + '\0', 
             fFlags = FileOperationFlags.FOF_ALLOWUNDO | flags 
            }; 

      // important to double-terminate the string. 
      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 SendSilent(string path) 
    { 
     return Send(path, FileOperationFlags.FOF_NOCONFIRMATION | FileOperationFlags.FOF_NOERRORUI | FileOperationFlags.FOF_SILENT); 

    } 
} 

}

有办法解决它,所以它在x64工作也很好?我尝试过使用ulong和其他修改,但它不起作用。

我知道还有其他解决方案需要参考Microsoft.VisualBasic,但我更喜欢p/invoke方式。

正确答案是:

在x64,则必须SHFILEOPSTRUCT未经包= 1个参数被声明,否则会失败。如果你希望你的代码独立于平台,那么这是一个真正的痛苦,因为你必须声明两个独立的结构,一个是Pack = 1,另一个没有。然后您必须声明两个不同的SHFileOperation调用,每个调用一个结构。然后,您必须决定要调用哪一个,具体取决于您是在32位还是64位运行。

你看过PInvoke网站吗?它有一个与FILEOPSTRUCT类型稍有不同的定义,强制Unicode有一件事。我想知道charset = auto是否会令人困惑......比如它默认为32位的ANSI,但64位的Unicode和中间的某处出错。

编辑; 此外,Visual Basic的参考方法是一个简单的...我知道人们有一种厌恶,出于某种原因,但相关的DLL仍然是核心框架的一部分,所以你不会添加任何新的依赖关系。

+0

问题存在于[StructLayout(LayoutKind.Sequential,CharSet = CharSet.Auto,Pack = 1)]中。对于64位,你需要删除包= 1,它的工作原理!既然你指向我的PInvoke网站,它甚至会在那里说出它的位置(在文章的底部,当它是64位的操作系统时,删除Pack = 1!) – MadBoy 2010-02-26 17:56:42

+0

哈哈,我甚至没有向下滚动,只是看到了差异 – 2010-02-26 18:32:15

+0

我使用64位Windows 7,Pack = 1作为FILEOPSTRUCT,它可以和我一起工作,没有任何问题:| – TheBlueSky 2011-03-18 18:19:36

看起来很奇怪,.NET已经具有删除回收站的功能......但它们位于Microsoft.VisualBasic名称空间中。具体来说,Microsoft.VisualBasic.FileIO

using Microsoft.VisualBasic.FileIO; 

// class declaration, method start here 

// Send file to recycle bin without dialog 
FileSystem.DeleteFile("pathToFile", UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin); 

// Send file to recycle bin without dialog 
FileSystem.DeleteFile("pathToFile", UIOption.AllDialogs, RecycleOption.SendToRecycleBin); 

// Directories are the same, but with DeleteDirectory instead 
+0

确实尴尬...... – RvdK 2010-02-26 15:46:25

+0

我知道这个解决方案,但是更喜欢没有使用VisualBasic的引用。 – MadBoy 2010-02-26 15:49:06

+0

@MadBoy为什么你想避免引用Microsoft.VisualBasic? – Nick 2010-02-26 17:27:16