5 Replies - 23890 Views - Last Post: 17 March 2010 - 02:39 PM Rate Topic: -----

#1 PsychoCoder   User is offline

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

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

Play with Recycle Bin in code

Posted 11 March 2010 - 11:07 PM

I am working on adding some functionality to an application and it consists of emptying the recycle bin (completed) but am wanting to list all the files currently in the bin. As you know there's going to need to be some Win32 API. This is what I've come up with (thus far) for getting the path to a special folder (such as Recycle Bin). Want to let me know if I'm headed down the right path?

Win32 API:
[DllImport("Shell32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
public static extern long SHGetSpecialFolderLocation(IntPtr hwndOwner, long nFolder, XPUtilitiesPro.Core.RecycleBin.ITEMIDLIST pidl);
[DllImport("Shell32.dll", EntryPoint = "SHGetPathFromIDListA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
public static extern long SHGetPathFromIDList(long pidl, StringBuilder pszPath);



Constants:
//// The Desktop - virtual folder
private const  long CSIDL_DESKTOP = 0x0;
//// Program Files
private const  long CSIDL_PROGRAMS = 2;
//// Control Panel - virtual folder
private const  long CSIDL_CONTROLS = 3;
//// Printers - virtual folder
private const  long CSIDL_PRINTERS = 4;
//// My Documents
private const  long CSIDL_DOCUMENTS = 5;
//// Favourites
private const  long CSIDL_FAVORITES = 6;
//// Startup Folder
private const  long CSIDL_STARTUP = 7;
//// Recent Documents
private const  long CSIDL_RECENT = 8;
//// Send To Folder
private const  long CSIDL_SENDTO = 9;
//// Recycle Bin - virtual folder
private const  long CSIDL_BITBUCKET = 10;
//// Start Menu
private const  long CSIDL_STARTMENU = 11;
//// Desktop folder
private const  long CSIDL_DESKTOPFOLDER = 16;
//// My Computer - virtual folder
private const  long CSIDL_DRIVES = 17;
//// Network Neighbourhood - virtual folder
private const  long CSIDL_NETWORK = 18;
//// NetHood Folder
private const  long CSIDL_NETHOOD = 19;
//// Fonts folder
private const  long CSIDL_FONTS = 20;
//// ShellNew folder
private const  long CSIDL_SHELLNEW = 21;

public const int MAX_PATH = 260;



Class structs:
public struct SHITEMID
{
    public long cb;
    public byte abID;
}

public struct ITEMIDLIST
{
    public SHITEMID mkid;
}



And now the method to get the path
public string GetFolderPath(long folderCSIDL)
{
    string folderPath = "";
    ITEMIDLIST IDL = default(ITEMIDLIST);
    //
    // Retrieve info about system folders such as the "Recent Documents" folder.
    // Info is stored in the IDL structure.
    //
    if (Win32.SHGetSpecialFolderLocation(this.handle, folderCSIDL, IDL) == 0) 
    {
        //
        // Get the path from the ID list, and return the folder.
        //
        StringBuilder  sb = new StringBuilder(MAX_PATH);
        if (Win32.SHGetPathFromIDList(IDL.mkid.cb, sb) == 0)
            folderPath = sb.ToString().Substring(0, ((sb.ToString().IndexOf('\0') + 1) - 1)) + "";	       
    }
    return folderPath;
}



Now, someone want to tell me I'm way off and there's an easier way to do what I'm looking to accomplish.

Is This A Good Question/Topic? 0
  • +

Replies To: Play with Recycle Bin in code

#2 PsychoCoder   User is offline

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

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

Re: Play with Recycle Bin in code

Posted 14 March 2010 - 09:10 PM

So far I have figured out how to get a list of all files in the Recycle Bin. It's not as straight forward as I initially thought because the Recycle Bin doesnt have a physical location, it's a virtual folder. To make this work you need to add a reference to shell32.dll (located in %SystemRoot%\system32\shell32.dll).

This code if from a console application I made for testing different ideas for this. So to list everything in your Recycle Bin you can use this

public static void Main(string[] args)
{
    Shell shell = new Shell();
    Folder folder = shell.NameSpace(0x000a);


    foreach (FolderItem2 item in folder.Items())
        Console.WriteLine("FileName:{0}", item.Name);
        

    Marshal.FinalReleaseComObject(shell);
    Console.ReadLine();
}



That will list everything in the Recycle Bin. Next we can use a recursive method for getting the size of each item. This method will get the size, after determining if the item is a folder or a file, if it's a folder it will go through each file in the folder and total up the total size of everything in the folder, otherwise it will just get the size of the file.

public static double CalculateSize(FolderItem obj)
{

    if (!obj.IsFolder)
        return (double)obj.Size;

    Folder recycleBin = (Folder)obj.GetFolder;

    double size = 0;


    foreach (FolderItem2 item in recycleBin.Items())
        size += CalculateSize(item);

    return size;

}



Now we can change the initial code to accommodate this new method to this

public static void Main(string[] args)
{
    Shell shell = new Shell();
    Folder folder = shell.NameSpace(0x000a);


    foreach (FolderItem2 item in folder.Items())
        Console.WriteLine("FileName:{0}     Size:{1} bytes", item.Name, CalculateSize(item));
        

    Marshal.FinalReleaseComObject(shell);
    Console.ReadLine();
}



More to come as I test, then I'm going to write a nice tutorial on how to do this. What's next you ask, well now on to how to restore an item from the Recycle Bin to it's original location so stay tuned
Was This Post Helpful? 0
  • +
  • -

#3 PsychoCoder   User is offline

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

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

Re: Play with Recycle Bin in code

Posted 17 March 2010 - 12:14 PM

So who wants to do some research on this for me? What I'm trying to do now is get 2 pieces of information I cannot figure out for the life of me; Date the file was deleted and it's original location.

I can get the file type, file size, it's size and it's recycle bin path (though it's not really a path since the recycle bin is a virtual folder), it's last modified date (but that's not the deleted date) and it's name.

I can restore the file just fine, but would like to be able to show it's original path like in the Windows recycle bin. This is all being done with the Shell32.dll, and I'll be writing a nice tutorial on doing this once I get everything done.
Was This Post Helpful? 0
  • +
  • -

#4 MentalFloss   User is offline

  • .
  • member icon

Reputation: 619
  • View blog
  • Posts: 1,590
  • Joined: 02-September 09

Re: Play with Recycle Bin in code

Posted 17 March 2010 - 01:13 PM

This is pretty slick but I'm curious why the application needs to see in the recycling bin. I'm just having a hard time understanding the practical reasons behind it. None the less, nice bit of code there.
Was This Post Helpful? 0
  • +
  • -

#5 Gonzilla   User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 23
  • Joined: 16-March 10

Re: Play with Recycle Bin in code

Posted 17 March 2010 - 01:51 PM

@MentalFloss:
It could be a small part in a recovery program for computer beginners, who donīt know how to use the recycle bin :D
Was This Post Helpful? 0
  • +
  • -

#6 PsychoCoder   User is offline

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

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

Re: Play with Recycle Bin in code

Posted 17 March 2010 - 02:39 PM

MentalFloss it's part of a utilities program I am developing.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1