2010-02-26 61 views
3

我有這個類似乎在非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位運行。

回答

2

你看過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

6

看起來很奇怪,.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