Page 1 of 1

Working with the Windows Recycle Bin with C#

#1 PsychoCoder  Icon User is offline

  • Google.Sucks.Init(true);
  • member icon

Reputation: 1633
  • View blog
  • Posts: 19,853
  • Joined: 26-July 07

Posted 26 March 2010 - 05:01 PM

Recently I needed to interact with the Windows Recycle Bin for a utilities application I've been asked to create for a client, and from step 1 I knew I was in for a surprise. Since the recycle bin doesn't exactly exist, meaning it's a virtual folder and doesn't have an actual location, getting information from it turned out to be more of a task than initially thought.

I initially thought of Win32 to accomplish this but kept running into a dead end. Now I'm sure that buried somewhere deep in the Win32 API list is one that will do what I was looking for, but after a couple days of trial and error I abandoned that idea and started looking at different options. What I came up with was using the Shell32.dll (located in %%WinDir%%/System32) and was able to come up with what I was looking for. And that is the premise on this short series on working with the Windows Recycle Bin.

In this series we will look at some functionality the Shell32.dll gives you for working with the Windows Recycle Bin. In this first entry we will look at how we can do 2 things:

  • List all the files in the Recycle Bin
  • Display the size of each item


To get you started open Visual Studio 2008 and create a new console application (these examples will be using a console application to begin with, when we get to other functionality we will switch to using a WinForms application, and you'll see why when we get there), don't worry when we are done you will be able to simply move our class file to the Windows application, so no need to rewrite everything we're currently working on.

Once you have your console application created add a new class (I named mine RecycleBin.cs oddly enough), then go to Project > Add Reference. Once the dialog opens click the Browse tab and navigate to your Windows directory (for me it's C:\Windows\Sytem32, I'm running Windows 7 Ultimate), scroll down and select Shell32.dll and click OK. We now had added our DLL, now we need to add our using statement, so add this to the top of your class

using Shell32;



To make things simpler on us let's create a class (do it inside the class you just created), I know this isn't the 100% best way to organize your code but it's ok in my opinion. Let's call this class RecycleBinItem, so for now your RecycleBin class should look like this

using System;
using System.Collections.Generic;
using System.Text;
using Shell32;
using System.Runtime.InteropServices;

namespace RecycleBinSample
{
    public class RecycleBinItem
    {
        public string FileName { get; set; }
        public string FileType { get; set; }
        public string FileSize { get; set; }
    }

    public class RecycleBin
    {
    }
}



The RecycleBinItem will be used in conjunction with Generics to hold the items in our recycle bin. Ok, first let's working on getting all the items in our recycle bin into a generic list of type RecycleBinItem. To do this we're going to use some of the items available to us in the Shell32.dll:

  • Folder: Represents a Shell folder. This object contains properties and methods that allow you to retrieve information about the folder.
  • Namespace: Creates and returns a Folder object for the specified folder. (In this case we're passing 10, which is the Recycle Bin)
  • FolderItem: Represents an item in a Shell folder. This object contains properties and methods that allow you to retrieve information about the item.
  • FolderItem2: Extends the FolderItems object


So, first let's take a look at listing everything in our Recycle Bin, this simple method does just that

public List<RecycleBinItem> GetRecycleBinItems()
{
    try
    {
        //create a new isntance of the Shell32 interface
        Shell shell = new Shell();
        List<RecycleBinItem> list = new List<RecycleBinItem>();

        //create a folder item to our Recycle Bin
        Folder recycleBin = shell.NameSpace(10);

        //now let's loop through all the Items in our Folder object
        //and add them to a generic list
        foreach (FolderItem2 f in recycleBin.Items())
            list.Add(
                    new RecycleBinItem
                    {
                        FileName = f.Name,
                        FileType = f.Type,
                        FileSize = GetSize(f).ToString()
                    });

        //release
        Marshal.FinalReleaseComObject(shell);

        //return the list
        return list;
    }
    catch (Exception ex)
    {
        Console.WriteLine(string.Format("Error accessing the Recycle Bin: {0}", ex.Message));
        return null;
    }
}



Now isn't that simple? Took me several days to realize that I was over-complicating this, and was ready to pull my hair out. That gives us a list of the files in our bin, the file name and what type of file it is (text file, XML file, etc), but as you can imagine we're not finished yet. The other task I said we would be covering was getting the size of each item in the Recycle Bin. For this we need to know something, is the item a folder ot just a file (this determines how we calculate size). If it's not a folder we simply return it's size, whereas if it's a folder we need to get into the folder and get the size of everything in it, returning the overall size of the folder.

We will do this with recursion like so

public double GetSize(FolderItem folderItem)
{
    //check if it's a folder, if it's not then return it's size
    if (!folderItem.IsFolder)
        return (double)folderItem.Size;

    //create a new Shell32.Folder item
    Folder folder = (Folder)folderItem.GetFolder;

    double size = 0;

    //since we're here we're dealing with a folder, so now we will loop
    //through everything in it and get it's size, thus calculating the
    //overall size of the folder
    foreach (FolderItem2 f in folder.Items())
        size += GetSize(f);

    //return the size
    return size;

}



Now that we have this in place we can alter our GetRecycleBinItems method to add the size to our list. The altered version looks like this

public List<RecycleBinItem> GetRecycleBinItems()
{
    try
    {
        //create a new isntance of the Shell32 interface
        Shell shell = new Shell();
        List<RecycleBinItem> list = new List<RecycleBinItem>();

        //create a folder item to our Recycle Bin
        Folder recycleBin = shell.NameSpace(10);

        //now let's loop through all the Items in our Folder object
        //and add them to a generic list
        foreach (FolderItem2 f in recycleBin.Items())
            list.Add(
                    new RecycleBinItem
                    {
                        FileName = f.Name,
                        FileType = f.Type,
                        FileSize = GetSize(f).ToString()
                    });
        //return the list
        return list;
    }
    catch (Exception ex)
    {
        Console.WriteLine(string.Format("Error accessing the Recycle Bin: {0}", ex.Message));
        return null;
    }
}



Ahh, now we have a list of everything currently in our Recycle Bin so now let's display it and see if it's correct. To do this we simply loop through our list and write it to the console like this

static void Main(string[] args)
{
    RecycleBin bin = new RecycleBin();

    Console.WriteLine("Items In Recycle Bin");
    //now loop through our list
    foreach (RecycleBinItem item in bin.GetRecycleBinItems())
        Console.WriteLine(string.Format("File: {0} => Size: {1} => Type: {2}", item.FileName, item.FileSize, item.FileType));

    Console.ReadLine();
}



And that should show you each file in your Recycle Bin, it's size and it's file type. Now I know it's a crude display and you can format it however you wish. This was just to show how to do it.

And there you have it, a way to show how to list everything in your Recycle Bin. Much easier than you initially thought isn't it? Be honest, because I know when I went down this path I thought it would be a lot harder as well.

Well that's the end of Part I, in Part II we will look at restoring a file in the Recycle Bin to it's original location, and emptying your Recycle Bin, so stay tuned and thanks for reading :)

Is This A Good Question/Topic? 3
  • +

Replies To: Working with the Windows Recycle Bin with C#

#2 X@MPP  Icon User is offline

  • 僕わ馬鹿ですね?
  • member icon

Reputation: 36
  • View blog
  • Posts: 1,014
  • Joined: 20-February 09

Posted 27 March 2010 - 09:43 PM

nice :) looks useful
Was This Post Helpful? 0
  • +
  • -

#3 Guest_VB.Terry*


Reputation:

Posted 30 March 2010 - 10:09 AM

May I convert the code and make a tutorial in vb.net. I would give you full credit since you made the original tutorial.
Was This Post Helpful? 0

#4 TENware  Icon User is offline

  • New D.I.C Head

Reputation: -1
  • View blog
  • Posts: 2
  • Joined: 27-August 11

Posted 27 August 2011 - 11:59 AM

Nice work!
I have, however, discovered a problem with the GetSize() function, or more correctly the Shell functions/methods/properties.

folderItem.IsFolder returns false even if the item is a folder
(Type = "File Folder").
Since the type is "File Folder", folderItem.Size returns 0.

You can use the shell32.dll API SHQueryRecycleBin() to get the number of items and total size (in bytes)
see:
http://www.pinvoke.n...RecycleBin.html
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1