Chapter 19
File System Objects

What’s in This Chapter

  • Directory and File classes
  • DriveInfo, DirectoryInfo, and FileInfo classes
  • FileSystemWatcher and Path classes
  • Managing the recycle bin

Wrox.com Downloads for This Chapter

Please note that all the code examples for this chapter are available as a part of this chapter’s code download on the book’s website at www.wrox.com/go/csharp5programmersref on the Download Code tab.

The preceding chapter described stream classes that you can use to read and write files. (It also described the File class, which isn’t a stream class but is just too useful to ignore when you use streams.) Those classes are handy but even those like StreamWriter that work at the highest levels still represent only the contents of files. They don’t give you any tools for working with the filesystem. Some of their methods can create a file, but they cannot rename or delete a file, or create or delete a directory.

This chapter describes classes that represent the filesystem. They allow you to create, rename, and delete files and directories. The final section in this chapter explains another important file-managing topic: how to use the recycle bin (wastebasket).

Filesystem Permissions

A program cannot perform a task unless the user has the appropriate permissions. Although this is true of every application, it’s a particular issue for those that work with files. Users need the appropriate permissions to read, write, create, and delete files and directories.

A common mistake is for developers to build and test an application from an account that has a lot of privileges. The program runs fine from the developer’s account, but normal users can’t use it because they don’t have the necessary privileges.

To ensure that users can use a program, you should always test it from an account that has typical user privileges.

.NET Framework Classes

The System.IO namespace provides several classes for working with the filesystem. The DirectoryInfo and FileInfo classes let you work with specific filesystem objects. For example, a FileInfo object represents a particular file and provides methods to create, rename, delete, and get information about that file.

The Directory and File classes provide static methods that you can use to manipulate the filesystem without creating instances of helper objects. For example, the Directory class’s Delete method lets you delete a directory without creating a DirectoryInfo object associated with the directory.

The following sections describe these and the other classes that the .NET Framework provides to help you work with the filesystem.

Directory

The Directory class provides static methods for working with directories. These methods let you create, rename, move, and delete directories. They also let you enumerate the files and subdirectories within a directory, and get and set directory information such as the directory’s creation and last access times.

The following table describes the Directory class’s static methods.

MethodPurpose
CreateDirectoryCreates a directory. This method creates ancestor directories if necessary.
DeleteDeletes a directory and its contents. This method can remove the entire directory tree.
ExistsReturns true if a path points to an existing directory.
GetCreationTimeReturns a directory’s creation date and time.
GetCreationTimeUtcReturns a directory’s creation date and time in Coordinated Universal Time (UTC).
GetCurrentDirectoryReturns the application’s current working directory.
GetDirectoriesReturns an array of strings holding the fully qualified names of a directory’s subdirectories.
GetDirectoryRootReturns the directory root for a path, for example, C:.
GetFilesReturns an array of strings holding the fully qualified names of a directory’s files. Optionally, you can search for files that match a pattern and you can search subdirectories.
GetFileSystemEntriesReturns an array of strings holding the fully qualified names of a directory’s files and subdirectories. Optionally, you can search for files and directories that match a pattern and you can search subdirectories.
GetLastAccessTimeReturns a directory’s last access date and time.
GetLastAccessTimeUtcReturns a directory’s last access date and time in UTC.
GetLastWriteTimeReturns the date and time when a directory was last modified.
GetLastWriteTimeUtcReturns the date and time in UTC when a directory was last modified.
GetLogicalDrivesReturns an array of strings listing the system’s logical drives as in A:. The list includes only drives that are attached. For example, it lists an empty floppy drive and a connected flash drive but doesn’t list a flash drive after you disconnect it.
GetParentReturns a DirectoryInfo object representing a directory’s parent.
MoveMoves a directory and its contents to a new location on the same disk volume.
SetCreationTimeSets a directory’s creation date and time.
SetCreationTimeUtcSets a directory’s creation date and time in UTC.
SetCurrentDirectorySets the application’s current working directory.
SetLastAccessTimeSets a directory’s last access date and time.
SetLastAccessTimeUtcSets a directory’s last access date and time in UTC.
SetLastWriteTimeSets a directory’s last write date and time.
SetLastWriteTimeUtcSets a directory’s last write date and time in UTC.

File

The preceding chapter mentioned the File class and specifically its Exists method. This class provides many other static methods for working with files. These methods let you create, rename, move, and delete files. They also make working with file streams a bit easier.

The following table describes the File class’s most useful static methods.

MethodPurpose
AppendAllLinesAdds text to the end of a file, creating it if it doesn’t exist.
AppendTextOpens a file for appending UTF-8 encoded text and returns a StreamWriter object attached to it.
CopyCopies a file.
CreateCreates a new file and returns a FileStream attached to it.
CreateTextCreates or opens a file for writing UTF-8 encoded text and returns a StreamWriter object attached to it.
DeletePermanently deletes a file.
ExistsReturns true if the specified file exists.
GetAttributesGets a file’s attributes. This is a combination of FileAttributes flags that can include Archive, Compressed, Device, Directory, Encrypted, IntegrityStream, Hidden, Normal, NoScrubData, NotContextIndexed, Offline, ReadOnly, ReparsePoint, SparseFile, System, and Temporary.
GetCreationTimeReturns a file’s creation date and time.
GetCreationTimeUtcReturns a file’s creation date and time in UTC.
GetLastAccessTimeReturns a file’s last access date and time.
GetLastAccessTimeUtcReturns a file’s last access date and time in UTC.
GetLastWriteTimeReturns a file’s last write date and time.
GetLastWriteTimeUtcReturns a file’s last write date and time in UTC.
MoveMoves a file to a new location.
OpenOpens a file and returns a FileStream attached to it. Parameters let you specify the mode (Append, Create, CreateNew, Open, OpenOrCreate, or Truncate), access (Read, Write, or ReadWrite), and sharing (Read, Write, ReadWrite, or None) settings.
OpenReadOpens a file for reading and returns a FileStream attached to it.
OpenTextOpens a UTF-8-encoded text file for reading and returns a StreamReader attached to it.
OpenWriteOpens a file for writing and returns a FileStream attached to it.
ReadAllBytesReturns a file’s contents in an array of bytes.
ReadAllLinesReturns a file’s lines in an array of strings.
ReadAllTextReturns a file’s contents in a string.
ReplaceTakes three file paths as parameters, representing a source file, a destination file, and a backup file. If the backup file exists, this method permanently deletes it. It then moves the destination file to the backup file, and moves the source file to the destination file.
SetAttributesSets a file’s attributes. This is a combination of flags defined by the FileAttributes enumeration. (See the GetAttributes method’s entry for the possible values.)
SetCreationTimeSets a file’s creation date and time.
SetCreationTimeUtcSets a file’s creation date and time in UTC.
SetLastAccessTimeSets a file’s last access date and time.
SetLastAccessTimeUtcSets a file’s last access date and time in UTC.
SetLastWriteTimeSets a file’s last write date and time.
SetLastWriteTimeUtcSets a file’s last write date and time in UTC.
WriteAllBytesCreates or replaces a file, writes an array of bytes into it, and closes the file.
WriteAllLinesCreates or replaces a file, writes an array of strings into it, and closes the file.
WriteAllTextCreates or replaces a file, writes a string into it, and closes the file.

DriveInfo

A DriveInfo object represents one of the computer’s drives. The following table describes the properties provided by this class. Note that some of these properties are available only when the drive is ready, as indicated in the following table’s Must Be Ready column. If you try to access them when the drive is not ready, C# throws an exception.

PropertyPurposeMust Be Ready
AvailableFreeSpaceReturns the amount of free space available on the drive in bytes.Yes
DriveFormatReturns the name of the filesystem type such as NTFS (NT File System) or FAT32 (32-bit File Allocation Table). (For a comparison of these, see www.ntfs.com/ntfs_vs_fat.htm.)Yes
DriveTypeReturns a DriveType enumeration value indicating the drive type. This value can be CDRom, Fixed, Network, NoRootDirectory, Ram, Removable, or Unknown.No
IsReadyReturns true if the drive is ready.No
NameReturns the drive’s name. This is the drive’s root name (as in A: or C:).No
RootDirectoryReturns a DirectoryInfo object representing the drive’s root directory. (See the following section “DirectoryInfo” for more information on this class.)No
TotalFreeSpaceReturns the total amount of free space on the drive in bytes.Yes
VolumeLabelGets or sets the drive’s volume label.Yes

The DriveInfo class also has a public static GetDrives method that returns an array of DriveInfo objects describing the system’s drives.

DirectoryInfo

A DirectoryInfo object represents a directory. You can use its properties and methods to create and delete directories and to move through a directory hierarchy. The following table describes the most useful public properties and methods provided by the DirectoryInfo class.

Property or MethodPurpose
AttributesGets or sets the directory’s attributes. This is a combination of FileAttributes flags that can include Archive, Compressed, Device, Directory, Encrypted, IntegrityStream, Hidden, Normal, NoScrubData, NotContextIndexed, Offline, ReadOnly, ReparsePoint, SparseFile, System, and Temporary.
CreateCreates the directory. (Create a DirectoryInfo object, passing its constructor the fully qualified name of a directory that doesn’t exist, and then use the Create method to create the directory.)
CreateSubdirectoryCreates a subdirectory within the directory and returns a DirectoryInfo object representing it. The subdirectory’s path is relative to the DirectoryInfo object’s directory, but can contain intermediate subdirectories.
CreationTimeGets or sets the directory’s creation time.
CreationTimeUtcGets or sets the directory’s creation time in UTC.
DeleteDeletes the directory if it is empty. A parameter lets you tell the object to delete its contents, too, if it isn’t empty.
ExistsReturns true if the directory exists.
ExtensionReturns the extension part of the directory’s name. Normally, this is an empty string for directories.
FullNameReturns the directory’s fully qualified path.
GetDirectoriesReturns an array of DirectoryInfo objects representing the directory’s subdirectories. An optional parameter gives a pattern to match. This method does not recursively search the subdirectories.
GetFilesReturns an array of FileInfo objects representing files inside the directory. An optional parameter gives a pattern to match. This method does not recursively search subdirectories.
GetFileSystemInfosReturns a strongly typed array of FileSystemInfo objects, representing subdirectories and files inside the directory. The items in the array are DirectoryInfo and FileInfo objects (both of which inherit from FileSystemInfo). An optional parameter gives a pattern to match. This method does not recursively search subdirectories.
LastAccessTimeGets or sets the directory’s last access time.
LastAccessTimeUtcGets or sets the directory’s last access time in UTC.
LastWriteTimeGets or sets the directory’s last write time.
LastWriteTimeUtcGets or sets directory’s last write time in UTC.
MoveToMoves the directory and its contents to a new path.
NameThe directory’s name without the path information.
ParentReturns a DirectoryInfo object, representing the directory’s parent. If the directory is its file system’s root (for example, C:), this returns null.
RefreshRefreshes the DirectoryInfo object’s data.
RootReturns a DirectoryInfo object representing the root of the directory’s file system.
ToStringReturns the directory’s fully qualified path and name.

FileInfo

A FileInfo object represents a file. You can use its properties and methods to create and delete files. The following table describes the most useful public properties and methods provided by the FileInfo class.

Property or MethodPurpose
AppendTextReturns a StreamWriter that appends text to the file.
AttributesGets or sets the file’s attributes. This is a combination of FileAttributes flags that can include Archive, Compressed, Device, Directory, Encrypted, IntegrityStream, Hidden, Normal, NoScrubData, NotContextIndexed, Offline, ReadOnly, ReparsePoint, SparseFile, System, and Temporary.
CopyToCopies the file and returns a FileInfo object, representing the new file. A parameter lets you indicate whether the copy should overwrite an existing file. If the destination path is relative, it is relative to the application’s current directory, not to the FileInfo object’s directory.
CreateCreates the file and returns a FileStream object attached to it. (Create a FileInfo object, passing its constructor the name of a file that doesn’t exist, and then call the Create method to create the file.)
CreateTextCreates the file and returns a StreamWriter attached to it. (Create a FileInfo object, passing its constructor the name of a file that doesn’t exist, and then call the CreateText method to create the file.)
CreationTimeGets or sets the file’s creation time.
CreationTimeUtcGets or sets the file’s creation time in UTC.
DeleteDeletes the file.
DirectoryReturns a DirectoryInfo object representing the file’s directory.
DirectoryNameReturns the name of the file’s directory.
ExistsReturns true if the file exists.
ExtensionReturns the extension part of the file’s name. For example, the extension for scores.txt is .txt.
FullNameReturns the file’s fully qualified path and name.
IsReadOnlyReturns true if the file is marked read-only.
LastAccessTimeGets or sets the file’s last access time.
LastAccessTimeUtcGets or sets the file’s last access time in UTC.
LastWriteTimeGets or sets the file’s last write time.
LastWriteTimeUtcGets or sets the file’s last write time in UTC.
LengthReturns the number of bytes in the file.
MoveToMoves the file to a new location. If the destination uses a relative path, it is relative to the application’s current directory, not to the FileInfo object’s directory. When this method finishes, the FileInfo object is updated to refer to the file’s new location.
NameThe file’s name without the path information.
OpenOpens the file with various mode (Append, Create, CreateNew, Open, OpenOrCreate, or Truncate), access (Read, Write, or ReadWrite), and sharing (Read, Write, ReadWrite, or None) settings. This method returns a FileStream object attached to the file.
OpenReadReturns a read-only FileStream attached to the file.
OpenTextReturns a StreamReader with UTF-8 encoding attached to the file for reading.
OpenWriteReturns a write-only FileStream attached to the file.
RefreshRefreshes the FileInfo object’s data.
ReplaceTakes three file paths as parameters, representing a source file, a destination file, and a backup file. If the backup file exists, this method permanently deletes it. It then moves the destination file to the backup file, and moves the source file to the destination file.
ToStringReturns the file’s fully qualified name.

FileSystemWatcher

The FileSystemWatcher class keeps an eye on part of the file system and raises events to let your program know if something changes. For example, a FileSystemWatcher can monitor a directory and raise an event when a new file appears so your program can process the file.

The FileSystemWatcher class’s constructor takes parameters that tell it which directory to watch and that give it a filter for selecting files to watch. For example, the filter *.txt makes it watch for changes to text files. The default filter is *.*, which catches changes to all files that have extensions.

The following table describes the FileSystemWatcher class’s most useful properties.

PropertyPurpose
EnableRaisingEventsDetermines whether the watcher is enabled. (This property is false by default, so the watcher does not raise any events until you set it to true.)
FilterDetermines the files for which the watcher reports events. (You cannot watch for multiple file types as in *.txt and *.dat. Instead use multiple FileSystemWatchers.)
IncludeSubdirectoriesDetermines whether the object watches subdirectories below the main directory.
InternalBufferSizeDetermines the size of the internal buffer. If the watcher is monitoring a very active directory, a small buffer may overflow.
NotifyFilterDetermines the types of changes that the watcher reports. This is a combination of values defined by the NotifyFilters enumeration and can include the values Attributes, CreationTime, DirectoryName, FileName, LastAccess, LastWrite, Security, and Size.
PathDetermines the path of the directory to watch.

The FileSystemWatcher class provides only two useful methods. The first method, Dispose, releases resources used by the component. As usual, be sure to call Dispose when you are done with the object (or use a using statement).

The second method, WaitForChanged, waits for a change synchronously (with an optional timeout). When a change occurs, the method returns a WaitForChangedResult object, giving information about the change that occurred.

When the FileSystemWatcher detects a change asynchronously, it raises an event to let the program know what has happened. The following table describes the class’s events.

NameDescription
ChangedA file or subdirectory has changed.
CreatedA file or subdirectory was created.
DeletedA file or subdirectory was deleted.
ErrorThe watcher’s internal buffer overflowed.
RenamedA file or subdirectory was renamed.

Path

The Path class provides static properties and methods that you can use to manipulate paths. Its methods return the path’s filename, extension, directory name, and so forth.

Other methods provide values that relate to system-generated paths. For example, they can give you the system’s temporary directory path or the name of a temporary file.

The following table describes the Path class’s most useful public properties.

PropertyPurpose
AltDirectorySeparatorCharReturns the alternative character used to separate directory levels in a hierarchical path. Typically, this is /.
DirectorySeparatorCharReturns the character normally used to separate directory levels in a hierarchical path. Typically, this is (as in C:UsersRodPhoneProjectsMrBones.sln).
InvalidPathCharsReturns a character array that holds characters that are not allowed in a path string. Typically, this array includes characters such as , <, >, and |, as well as nonprintable characters such as those with ASCII values between 0 and 31.
PathSeparatorReturns the character used to separate path strings in environment variables. Typically, this is a semicolon (;).
VolumeSeparatorCharReturns the character placed between a volume letter and the rest of the path. Typically, this is a colon (:) as in C:.

The following table describes the Path class’s most useful methods.

MethodPurpose
ChangeExtensionChanges a path’s extension.
CombineReturns two path strings concatenated.
GetDirectoryNameReturns a path’s directory.
GetExtensionReturns a path’s extension.
GetFileNameReturns a path’s filename and extension.
GetFileNameWithoutExtensionReturns a path’s filename without the extension.
GetFullPathReturns a path’s fully qualified value.
GetInvalidFileNameCharsReturns an array listing characters that are invalid in filenames.
GetInvalidPathCharsReturns an array listing characters that are invalid in file paths.
GetPathRootReturns a path’s root directory string.
GetRandomFileNameReturns a random filename.
GetTempFileNameCreates a uniquely named, empty temporary file and returns its fully qualified path. Your program can open that file for scratch space, do whatever it needs to do, close the file, and then delete it. A typical filename might be C:UsersRodAppDataLocalTemp mpD4F0.tmp.
GetTempPathReturns the path to the system’s temporary folder. This is the path part of the filenames returned by GetTempFileName.
HasExtensionReturns true if a path includes an extension.
IsPathRootedReturns true if a path is an absolute path. This includes C:TestsLogs.txt and ClientsLitigation, but not LostFilesPeter.txt or .Jokes.

Using the Recycle Bin

Unfortunately, C# doesn’t include methods for working with the recycle bin. However, you can use a combination of three different techniques: using the FileIO.FileSystem class, using API functions, and using Shell32.Shell.

The ManageRecycleBin example program, which is available for download on this book’s website, demonstrates the techniques described in the following sections. Enter a file or directory name and click the corresponding Delete button to move that item into the recycle bin. Click Refresh to refresh the list of files in the recycle bin. Click Empty to permanently remove all the files from the recycle bin. Finally, right-click a file in the recycle bin to see a context menu giving commands you can apply to that file, as shown in Figure 19-1.

c19f001.tif

Figure 19-1: The ManageRecycleBin example program lets you view and manipulate the files in the recycle bin.

You may want to download the ManageRecycleBin example program so that you can refer to it as you read the following sections.

Using the FileIO.FileSystem Class

The Microsoft.VisualBasic.FileIO namespace includes a FileSystem class that provides DeleteDirectory and DeleteFile methods. Those methods can take an optional parameter that indicates whether you want to move the directory or file into the recycle bin, or whether you want to delete the directory or file permanently. (They can also take a parameter that lets you decide whether the methods should display progress dialogs.)

Some C# developers prefer not to use classes defined in the Microsoft.VisualBasic namespace, feeling they are somehow not C#ish enough. Personally, I think that’s just plain silly. If the Microsoft.VisualBasic namespace includes tools that you can use to make your life easier, you’re only hurting yourself by ignoring them. This class is in the .NET Framework, so it’s not like you’re sneaking around using some sort of substandard back alley code.

The following code shows the event handlers the ManageRecycleBin program executes when you click one of its Delete buttons.

// Delete a file.
private void deleteFileButton_Click(object sender, EventArgs e)
{
    FileSystem.DeleteFile(fileTextBox.Text,
        UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin);
    fileTextBox.Clear();
    ListFiles();
}

// Delete a directory.
private void deleteDirectoryButton_Click(object sender, EventArgs e)
{
    FileSystem.DeleteDirectory(directoryTextBox.Text,
        UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin);
    directoryTextBox.Clear();
    ListFiles();
}

The first event handler deletes a file. It calls the FileSystem class’s DeleteFile method, passing it the name of the file to delete, a UIOption flag indicating the method should display only error messages (not animations or confirmation dialogs), and a RecycleOption value indicating the file should be moved to the recycle bin.

The code then clears the TextBox holding the file’s name and calls the ListFiles method. The ListFiles method uses Shell32.Shell, which is described shortly in the section “Using Shell32.Shell.”

Using API Functions

The FileIO.FileSystem class lets you easily move directories and files into the recycle bin, but it doesn’t give you any other tools for working with the recycle bin. It doesn’t let you determine the number or sizes of the items in the recycle bin, restore items from the recycle bin, or empty the recycle bin.

Fortunately, you can use the SHEmptyRecycleBin API function to empty the recycle bin relatively easily. This API function takes a parameter that is of the RecycleFlags enumerated type. (Actually, the function itself takes a uint as a parameter, but the enumeration makes it easier for your code to specify the wanted options.) The following code shows the enumeration’s definition.

[Flags]
private enum RecycleFlags : uint
{
    SHERB_NOCONFIRMATION = 0x1,
    SHERB_NOPROGRESSUI = 0x2,
    SHERB_NOSOUND = 0x4
}

The following code shows the API function’s declaration.

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

Here shell32.dll is the library that contains the SHEmptyRecycleBin API function. This is different from the Shell32.Shell techniques described in the next section.

The ManageRecycleBin program uses the following EmptyRecycleBin method, which wraps the call to SHEmptyRecycleBin.

public static void EmptyRecycleBin(bool showProgress, bool playSound,
    bool confirm)
{
    RecycleFlags options = 0;
    if (!showProgress) options |= RecycleFlags.SHERB_NOPROGRESSUI;
    if (!playSound) options |= RecycleFlags.SHERB_NOSOUND;
    if (!confirm) options |= RecycleFlags.SHERB_NOCONFIRMATION;

    SHEmptyRecycleBin(IntPtr.Zero, null, (uint)options);
}

This method uses its parameters to create an appropriate RecycleFlags value. It then simply invokes the API function.

When you click the Empty button, the program uses the following code to invoke the EmptyRecycleBin method.

// Empty the recycle bin.
private void emptyButton_Click(object sender, EventArgs e)
{
    // Empty with sounds and making the user confirm.
    EmptyRecycleBin(false, true, true);

    // Refresh the list.
    ListFiles();
}

Using Shell32.Shell

Shell32.Shell is an interface for working with the Windows shell. One of the things you can do with the Shell interface is interact with virtual objects representing such things as remote printers and the recycle bin.

The files in the recycle bin are represented by FolderItems. To work with the files, the ManageRecycleBin program needs to keep track of those FolderItems. To do so, it stores information about the files in the following RecycleItemInfo class.

// A class to hold a FolderItem and return its name.
private class RecycleItemInfo
{
    public FolderItem Item;
    public RecycleItemInfo(FolderItem item)
    {
        Item = item;
    }
    public override string ToString()
    {
        return Item.Name;
    }
}

This class simply holds a FolderItem. It provides a constructor for easy initialization and overrides its ToString method to return the name of the file it represents.

The following code shows the ManageRecycleBin program’s ListFiles method.

// List the files in the recycle bin.
private void ListFiles()
{
    const int RECYCLE_BIN_NAMESPACE = 10;

    Shell shell = new Shell();
    Folder bin = shell.NameSpace(RECYCLE_BIN_NAMESPACE);

    // List the files.
    filesListBox.Items.Clear();
    foreach (FolderItem item in bin.Items())
    {
        filesListBox.Items.Add(new RecycleItemInfo(item));
    }
}

The method creates a new Shell interface and uses its NameSpace method to get a Folder interface representing the recycle bin. The parameter, which has value 10, is simply the “magic number” that represents the recycle bin.

Next, the method empties the file ListBox and loops through the FolderItems returned by the recycle Folder’s Items method. For each FolderItem, the program creates a RecycleItemInfo object and adds it to the ListBox.

Because the RecycleItemInfo class’s ToString method returns the FolderItem’s Name property, that is what is displayed by the ListBox.

The following code shows how the program responds when you right-click a file’s entry in the ListBox.

// On right-mouse down, display the item's verbs in a menu.
private void filesListBox_MouseDown(object sender, MouseEventArgs e)
{
    // Make sure it's the right button.
    if (e.Button != MouseButtons.Right) return;

    // Find the item under the mouse.
    int index = filesListBox.IndexFromPoint(e.Location);
    if (index < 0) return;

    // Select that item.
    filesListBox.SelectedIndex = index;

    // Get the item's RecycleItemInfo.
    RecycleItemInfo info = filesListBox.SelectedItem as RecycleItemInfo;

    // Get the item's FolderInfo object.
    FolderItem item = info.Item;

    // Make the context menu.
    ContextMenu menu = new ContextMenu();
    foreach (FolderItemVerb verb in item.Verbs())
    {
        MenuItem menuItem = new MenuItem(verb.Name, ContextMenuItem_Click);
        menuItem.Tag = verb;
        menu.MenuItems.Add(menuItem);
    }
    menu.Show(filesListBox, e.Location);
}

This code creates a context menu appropriate for the item that the user right-clicked. First, the method exits if the button pressed isn’t the right mouse button.

Next, the program uses the ListBox’s IndexFromPoint method to get the index of the item under the mouse. If there is no item there, the method exits. If there is an item below the mouse, the code selects it.

The code then converts the selected item into the RecycleItemInfo object that is stored in the ListBox and gets the FolderItem stored inside the object.

The method then creates a ContextMenu and loops through the list returned by the FolderItem’s Verbs method. Each of those items is a FolderItemVerb interface that represents something the FolderItem can do.

The code creates a new MenuItem representing each verb. The MenuItem displays its verb’s name and is associated with the ContextMenuItem_Click event handler. The code stores the FolderItemVerb in the MenuItem’s Tag property.

After it has created the ContextMenu and the verbs’ MenuItems, the program displays the ContextMenu.

The following code shows the ContextMenuItem_Click event handler.

// Perform some action on a file.
private void ContextMenuItem_Click(object sender, EventArgs e)
{
    // Get the MenuItem.
    MenuItem menuItem = sender as MenuItem;

    // Get the verb.
    FolderItemVerb verb = menuItem.Tag as FolderItemVerb;

    // Invoke the verb.
    verb.DoIt();

    // Redisplay the files.
    ListFiles();
}

First, this code gets the MenuItem that was clicked. It gets the corresponding FolderItemVerb from the MenuItem’s Tag property. The code invokes the FolderItemVerb’s DoIt method to make it perform whatever action it should take. It finishes by calling ListFiles to refresh the file list in case the verb changed the files in the recycle bin, for example, by restoring a file.

Download the ManageRecycleBin program to see additional details. The program isn’t exactly simple, but it does demonstrate techniques you can use to work with the recycle bin.

Summary

The System.IO namespace offers many classes that let you manipulate files and directories. Classes such as Directory, DirectoryInfo, File, and FileInfo make it easy to create, examine, move, rename, and delete directories and files. The File class’s ReadAllText and WriteAllText methods make it particularly easy to read or write an entire file.

The FileSystemWatcher class lets an application keep an eye on a file or directory and take action when it is changed. For example, a program can watch a spooling directory and take action when a new file appears in it.

The Path class provides miscellaneous support for working with paths. For example, it provides methods you can use to combine paths and resolve relative paths.

There is considerable overlap among these tools, so you don’t need to feel that you have to use them all. Take a good look so that you know what’s there, and then pick the tools that you find the most comfortable.

Finally this chapter explained techniques you can use to manage the recycle bin. Some of them are fairly complex, but at least the FileIO.FileSystem class makes moving a file or directory into the recycle reasonably simple.

So far the chapters in this book have explained how to do things locally on the user’s computer. The next chapter explains how a program can move off of the local computer to download files from the Internet.

Exercises

  1. Write a program that lets the user select a directory and displays its creation, last access, and last write times.
  2. Write a program that lets the user select a file and displays its creation, last access, and last write times. Let the user change the times and then set them for the file.
  3. Write a program that lets the user get and set a file’s attributes. Use CheckBoxes to display and let the user specify attributes.
  4. Write a program that uses File.ReadAllText and File.WriteAllText to save and restore the contents of a text file when it starts and stops. Compare your solution to the solution for Exercise 18-3.
  5. Write a program that sorts the lines in a file. (Hint: Use File.ReadAllLines to get the lines, sort them, and then use File.WriteAllLines to write them back into the file.)
  6. Write a program that lists the computer’s drives and whatever drive information is available from the DriveInfo class.
  7. Modify the program you wrote for Exercise 6 so that it displays sizes in KB, MB, GB, or TB as appropriate.
  8. Write a program that displays the name of the directory two levels higher than the directory where the program is executing. What happens if you run the program near the top of the directory hierarchy, for example, in C:?
  9. Write a program that lets the user enter a directory path and a pattern. When the user clicks the Search button, the program should search the directory and its subdirectories for files matching the pattern.
  10. Modify the program you wrote for Exercise 9 so that it shows the selected filenames (without paths) and their sizes.
  11. Write a program that uses a FileSystemWatcher to watch the directory where the program is executing for changes. When a change occurs, the program should display the date and time, the type of change, and the changing file’s name.
  12. Write a program that lets the user enter a filename and then uses the FileIO class to move the file into the recycle bin. (That’s all many programs need to do anyway. You can use the recycle bin on your desktop to manage its contents.)
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
52.15.65.65