ShellBoost

Items enumeration

The first method that the Windows Shell will call in your ShellBoost namespace extension is the EnumItems method. Here is a simple example of such a method, that we saw in the “Writing your first extension” chapter:

public override IEnumerable<ShellItem> EnumItems(SHCONTF options)
{
    yield return new ShellFolder(this, new StringKeyShellItemId("My First Folder"));
    yield return new ShellItem(this, new StringKeyShellItemId("My First Item"));
}

This EnumItems method simply tells the Shell what Shell Items a given Shell Folder contains. However, it’s also used by ShellBoost when the Shell asks for one single item (for direct access, parsing, searching, etc.). For this reason, the ShellFolder class defines the two following methods that are called in these cases:

    /// Gets an item using its display name.
    protected virtual ShellItem GetItem(string displayName)
    {
        ... pseudo code
        return EnumItems(SHCONTF.SHCONTF_FOLDERS |
            SHCONTF.SHCONTF_NONFOLDERS |
            SHCONTF.SHCONTF_FLATLIST | // all items
            SHCONTF.SHCONTF_INCLUDEHIDDEN |
            SHCONTF.SHCONTF_INCLUDESUPERHIDDEN)?.FirstOrDefault(i => i.DisplayName.EqualsIgnoreCase(displayName));
    }
 
    /// Gets an item using its identifier.
    public virtual ShellItem GetItem(ShellItemId id)
    {
        ... pseudo code
        return EnumItems(SHCONTF.SHCONTF_FOLDERS |
            SHCONTF.SHCONTF_NONFOLDERS |
            SHCONTF.SHCONTF_FLATLIST | // all items
            SHCONTF.SHCONTF_INCLUDEHIDDEN |
            SHCONTF.SHCONTF_INCLUDESUPERHIDDEN)?.FirstOrDefault(i => i != null && i.Id != null && i.Id.EqualsOrSameBeginning(id));
    }

This is obviously not optimal, so it’s strongly recommended you override both these methods if your Shell Folder implementation must maximize performance.

Conditional enumeration UI

If you need to show a window (like a WPF or Winforms window) from your namespace extension, you cannot use ShellBoost implicit threads (threads implicitly created by RPC incoming calls from the Shell) because these threads are not STA (Single Threaded Apartement) threads, which is a common requirement for UI-bound objects.

So, you can create your own STA threads or use ShellBoost utilities for that. For example, here is how you can show a WPF window before enumerating items:

public override IEnumerable<ShellItem> EnumItems(SHCONTF options)
{
    // run code on an STA thread
    var ret = ShellBoost.Core.Utilities.TaskUtilities.StartSTAThreadTask(() =>
    {
        var win = new MyWpfWindow(); // create the WPF window
        return win.ShowDialog(); // show it as a modal dialog
    }).Result; // => the result of ShowDialog
    ...
}  

Note in this case the window is modal, so the requesting Shell object (a Windows Explorer view for example) will wait until the window is dismissed. In the case of a Windows Explorer view, it will usually show the green line progress:

Conditional enumeration UI - Picture 85