BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Input / Output
.NET 1.1+

Recycling Files and Folders Part 2

The second part of this two-part article revisits sending files and folders to the Windows Recycle Bin. In the first part we used the VisualBasic namespace to perform this task. In the second part we will make use of the Windows API through P/Invoke.

P/Invoke

The first instalment of this article examined the methods available for sending files and folders to the Recycle Bin using the FileSystem class in the Microsoft.VisualBasic.FileIO namespace. This provided a method of recycling files, rather than deleting them, using purely managed code.

In this part of the article we will look at a second method for using the Recycle Bin. This will utilise Platform Invocation Services (P/Invoke) to call functions in the Windows API. This provides a more complex manner of recycling files and folders that can be used when the more limited functionality of the FileSystem class is not suitable.

As we are using P/Invoke, it is useful to include the following using directive in the code:

using System.Runtime.InteropServices;

SHFileOperation Function

The Windows API function that is used for file operations such as deleting files and folders, or for sending them to the Recycle Bin, is named "SHFileOperation". The function is found in the shell32 dynamic linked library (DLL). To declare a reference to this function so that you may call it from managed code, include the following inside the code block of your class:

[DllImport("Shell32.dll")]
static extern int SHFileOperation([In] ref SHFILEOPSTRUCT lpFileOp);

The function accepts a single parameter containing the details of the operation to be carried out. This parameter is a structure containing eight fields, some of which are required and others that we will not use. The fields that we will utilise in this article are:

  • wFunc. This field determines the type of operation that will be executed. Various operations are available to allow copying, renaming, moving and deleting files. We will use the function name "FO_DELETE", which allows files and folders to be deleted or recycled.
  • pFrom. This field specifies the name of the file or folder to be deleted. It is a double null-terminated string that should contain the full path of the file or folder.
  • fFlags. This field specifies a set of flags that modify the behaviour of the file operation. There are several flags that can be combined with logical bitwise operators when recycling files and folders. We can define some of them as constants, as well as declaring the structure itself, using the following code within the class:
[StructLayout(LayoutKind.Sequential)]
public struct SHFILEOPSTRUCT
{
    public IntPtr hwnd;
    public uint wFunc;
    public string pFrom;
    public string pTo;
    public ushort fFlags;
    public int fAnyOperationsAborted;
    public IntPtr hNameMappings;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string lpszProgressTitle; 
}

private const int FO_DELETE = 0x0003;
private const int FOF_SILENT = 0x0004;
private const int FOF_ALLOWUNDO = 0x0040;
private const int FOF_NOCONFIRMATION = 0x0010;
private const int FOF_WANTNUKEWARNING = 0x4000;

In addition to the parameters, the SHFileOperation function returns an integer value. If the value is zero, the operation was successful. If it is any other value, an error occurred during the operation. The value returned is the error code that describes the problem. For more details about error codes, review the documentation provided by MSDN.

Sending Files to the Recycle Bin

As with the previous part of the article we will begin with the simplest operation. This sends a file to the Recycle Bin and provides an interactive process. When the command is issued, the user is presented with a dialog box that asks them to confirm that they wish to delete the file. If they answer, "Yes", the file is moved to the Recycle Bin. If they click the "No" button, the operation is cancelled.

To perform the recycling operation we must create a SHFILEOPSTRUCT structure containing three elements. The wFunc field must contain the delete command constant, "FO_DELETE". The pFrom value should be set to the name of the file to be deleted, including the full path, and should be double null-terminated. Finally, the fFlags field is set to FOF_ALLOWUNDO to indicate that the Recycle Bin is to be used.

To send a file named "RecycleMe.txt" from the "c:\Recycle" folder to the Recycle Bin, use the following code. Note the addition of the "\0\0" string to the file name to specify the double null string-termination.

SHFILEOPSTRUCT operation = new SHFILEOPSTRUCT();
operation.wFunc = FO_DELETE;
operation.pFrom = @"c:\Recycle\RecycleMe.txt" + "\0\0";
operation.fFlags = FOF_ALLOWUNDO;
int result = SHFileOperation(ref operation);

If you have already confirmed the deletion with the user, or if you do not require confirmation, you may not wish to show the confirmation dialog box. To remove this dialog box, include the FOF_NOCONFIRMATION flag.

SHFILEOPSTRUCT operation = new SHFILEOPSTRUCT();
operation.wFunc = FO_DELETE;
operation.pFrom = @"c:\Recycle\RecycleMe.txt" + "\0\0";
operation.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION;
int result = SHFileOperation(ref operation);

You should have noticed that the previous example did not request confirmation but did show a progress dialog box. This is more noticeable when you are deleting a large number of files or folders. It is likely that you will not wish to show this progress window. To hide it, add the FOF_SILENT flag.

SHFILEOPSTRUCT operation = new SHFILEOPSTRUCT();
operation.wFunc = FO_DELETE;
operation.pFrom = @"c:\Recycle\RecycleMe.txt" + "\0\0";
operation.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_SILENT;
int result = SHFileOperation(ref operation);

The last flag that we will consider is important when dealing with large files. Some files are too large to be placed into the Recycle Bin. When these are removed they are destroyed instead. To allow the user the opportunity to cancel the operation when such files will be erased, include the FOF_WANTNUKEWARNING flag. This provides a partial overriding of the FOF_NOCONFIRMATION flag where supported.

SHFILEOPSTRUCT operation = new SHFILEOPSTRUCT();
operation.wFunc = FO_DELETE;
operation.pFrom = @"c:\Recycle\RecycleMe.txt" + "\0\0";
operation.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_WANTNUKEWARNING;
int result = SHFileOperation(ref operation);
21 May 2009