Deadly-Bagel
Deadly-Bagel

Reputation: 1620

Send multiple directories to the Recycle Bin with FileSystem.DeleteDirectory

Making a file browser with loads of functions, coming back to fine tune some of my methods to find this:

foreach (ListViewItem item in listView1.SelectedItems)
{
    FileSystem.DeleteDirectory(item.SubItems[3].Text,  
        UIOption.AllDialogs,
        RecycleOption.SendToRecycleBin,
        UICancelOption.ThrowException);
}

which works great to send a SINGLE directory or file to the recycle bin, but it will prompt for every selected item. Not great for deleting a pile of files and folders.

Any way to achieve this without the excess prompts? Or do I have to delve into SHFILEOPSTRUCT?

Thanks for your help, so far 90% of my questions were already answered here, best website ever.

Upvotes: 1

Views: 364

Answers (2)

Steve
Steve

Reputation: 216313

This seems to be the only way to do what you have required
Moving the files and directory to the recycle bin without prompt

using System.Runtime.InteropServices;

class Win32ApiUtils
{
    // Don't declare a value for the Pack size. If you omit it, the correct value is used when  
    // marshaling and a single SHFILEOPSTRUCT can be used for both 32-bit and 64-bit operation.
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public struct SHFILEOPSTRUCT
    {
        public IntPtr hwnd;
        [MarshalAs(UnmanagedType.U4)]
        public int wFunc;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string pFrom;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string pTo;            
        public ushort fFlags;
        [MarshalAs(UnmanagedType.Bool)]
        public bool fAnyOperationsAborted;
        public IntPtr hNameMappings;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string lpszProgressTitle;
   }

   [DllImport("shell32.dll", CharSet = CharSet.Auto)]
   static extern int SHFileOperation(ref SHFILEOPSTRUCT FileOp);
   const int FO_DELETE = 3;
   const int FOF_ALLOWUNDO = 0x40;
   const int FOF_NOCONFIRMATION = 0x10; //Don't prompt the user.; 

   public static int DeleteFilesToRecycleBin(string filename)
   {
        SHFILEOPSTRUCT shf = new SHFILEOPSTRUCT();
        shf.wFunc = FO_DELETE;
        shf.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION;
        shf.pFrom = filename + "\0";  // <--- this "\0" is critical !!!!!
        int result = SHFileOperation(ref shf);
        // Any value different from zero is an error to lookup 
        return result;

   }

}

   foreach (ListViewItem item in listView1.SelectedItems)
   {
        int result = Win32ApiUtils.DeleteFilesToRecycleBin(item.SubItems[3].Text);
        if(result != 0) ...... // ??? throw ??? message to user and contine ???
   }

-- Warning -- This code needs to be tested. I have found the layout of SHFILEOPSTRUCT on PInvoke site and on that link there are some notes about the declaration of the strings used.

Well. tested on my Win7 64bit with a single directory to delete. Works like a charm....

Upvotes: 0

Reed Copsey
Reed Copsey

Reputation: 564671

If you don't want the prompts, you could use Directory.Delete instead of the FileSystem method. This will delete the directory and files and subdirectories (provided you specify that you want it to do so).

Upvotes: 4

Related Questions