Manage the recycle bin (wastebasket) in C#

[recycle bin]

You can use API functions to manage the recycle bin, but some operations are much easier if you use the Microsoft.VisualBasic library. You can use the API if you like, but I’d rather do things the easiest way possible to save time and avoid bugs.

To use the Microsoft.VisualBasic library, first add a reference to it. Then add a using statement to the code that will use the routines.

That library can help you move a file or directory into the recycle bin, but it can’t help you get the number of items in the recycle bin or empty it. For those tasks, you’re stuck using the API.

This example builds a Recycler class that provides static methods for moving files or directories into the recycle bin, getting the number of items in the recycle bin, and emptying the recycle bin.

The following code shows how the Recycler gets the number of files in the recycle bin.

// Structure used by SHQueryRecycleBin.
[StructLayout(LayoutKind.Sequential)]
private struct SHQUERYRBINFO
{
    public int cbSize;
    public long i64Size;
    public long i64NumItems;
}

// Get information from recycle bin.
[DllImport("shell32.dll")]
private static extern int SHQueryRecycleBin(string pszRootPath,
    ref SHQUERYRBINFO pSHQueryRBInfo);

// Empty the recycle bin.
[DllImport("shell32.dll")]
static extern int SHEmptyRecycleBin(IntPtr hWnd,
    string pszRootPath, uint dwFlags);

// Return the number of items in the recycle bin.

// Note: In Windows 2000, you need to supply the root
// directory to the call to SHQueryRecycleBin so to get
// the total number of files in the recycle you must add
// up the results for each disk. See:
// http://www.pinvoke.net/default.aspx/shell32/SHQueryRecycleBin.html
public static int NumberOfFilesInRecycleBin()
{
    SHQUERYRBINFO sqrbi = new SHQUERYRBINFO();
    sqrbi.cbSize = Marshal.SizeOf(typeof(SHQUERYRBINFO));
    int hresult = SHQueryRecycleBin(string.Empty, ref sqrbi);
    return (int)sqrbi.i64NumItems;
}

The code first defines the SHQUERYRBINFO structure, and the SHQueryRecycleBin API function. It also defines the SHEmptyRecycleBin API function for later use.

The NumberOfFilesInRecycleBin method calls the SHQueryRecycleBin API function and returns the i64NumItems parameter that it gets. (Yes, this is pretty ugly code. That’s why I prefer to use the Microsoft.VisualBasic library if possible.)

The following code shows how the Recycler deletes a file.

// Delete a file or move it to the recycle bin.
public static void DeleteFile(string filename, bool confirm,
    bool delete_permanently)
{
    UIOption ui_option = UIOption.OnlyErrorDialogs;
    if (confirm) ui_option = UIOption.AllDialogs;

    RecycleOption recycle_option =
        recycle_option = RecycleOption.SendToRecycleBin;
    if (delete_permanently)
        recycle_option = RecycleOption.DeletePermanently;

    try
    {
        FileSystem.DeleteFile(filename, ui_option, recycle_option);
    }
    catch (Exception ex)
    {
        MessageBox.Show("Error deleting file.\n" + ex.Message,
            "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

The code sets up some options that depend on the method’s parameters and then calls FileSystem.DeleteFile to delete the file.

The Recycler class’s DeleteDirectory method is very similar except it calls FileSystem.DeleteDirectory. See the code for details.

The following code shows how the Recycler empties the recycle bin.

// Empty the wastebasket.
[Flags]
private enum RecycleFlags : uint
{
    SHERB_NOCONFIRMATION = 0x1,
    SHERB_NOPROGRESSUI = 0x2,
    SHERB_NOSOUND = 0x4
}
public static void EmptyWastebasket(bool show_progress,
    bool play_sound, bool confirm)
{
    RecycleFlags options = 0;
    if (!show_progress) options =
        options | RecycleFlags.SHERB_NOPROGRESSUI;
    if (!play_sound)    options =
        options | RecycleFlags.SHERB_NOSOUND;
    if (!confirm)       options =
        options | RecycleFlags.SHERB_NOCONFIRMATION;

    try
    {
        SHEmptyRecycleBin(IntPtr.Zero, null, (uint)options);
    }
    catch (Exception ex)
    {
        MessageBox.Show("Error emptying wastebasket.\n" +
            ex.Message, "Error", MessageBoxButtons.OK,
            MessageBoxIcon.Error);
    }
}

The code first sets up the desired options and then calls the SHEmptyRecycleBin API function.

The Recycler class makes using these methods easy. For example, the following code shows how the main program deletes the file whose name is in the txtFile TextBox. The other parameters get their values from the CheckBox and RadioButton settings selected on the form.

// Delete the file.
private void btnDeleteFile_Click(object sender, EventArgs e)
{
    Recycler.DeleteFile(
        txtFile.Text,
        chkConfirmDelete.Checked,
        radDeletePermanently.Checked);
}

That’s all there is to it. It still mystifies me that Microsoft makes using the recycle bin so hard, but at least the Recycler class makes the process manageable.


Download Example   Follow me on Twitter   RSS feed   Donate




This entry was posted in files, system and tagged , , , , , , , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *