Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / Win32

.NET Shell Extensions - Shell Info Tip Handlers

4.90/5 (16 votes)
5 Apr 2013CPOL7 min read 56.4K   2K  
Rapidly create Shell Info Tip Extensions using .NET

Introduction

Shell Info Tip Handlers are DLLs that are registered in the system to customise tooltips for items in the shell. In this article, I will show you how to create an Info Tip Handler extension using .NET and a library called SharpShell.

Image 1

Above: An example Info Tip Handler Extension in action. This extension changes the Shell Tooltip for Folders to show the folder name, and the number of items it contains.

The Series

This article is part of the series '.NET Shell Extensions', which includes:

  1. .NET Shell Extensions - Shell Context Menus
  2. .NET Shell Extensions - Shell Icon Handlers
  3. .NET Shell Extensions - Shell Info Tip Handlers
  4. .NET Shell Extensions - Shell Drop Handlers
  5. .NET Shell Extensions - Shell Preview Handlers
  6. .NET Shell Extensions - Shell Icon Overlay Handlers
  7. .NET Shell Extensions - Shell Thumbnail Handlers
  8. .NET Shell Extensions - Shell Property Sheets

Our Goal

To show how SharpShell and Shell Info Tip Handlers work, we're going to create a DLL that changes the tooltips shown for folders. In our custom tooltip, we'll show the name of the folder and the number of items in the folder. The actual code to do this is trivial, to show how straightforward SharpShell will make this, here's the final class:

C#
/// <summary>
/// The FolderInfoTip handler is an example SharpInfoTipHandler that provides an info tip
/// for folders that shows the number of items in the folder.
/// </summary>
[ComVisible(true)]
[COMServerAssociation(AssociationType.Directory)]
public class FolderInfoTipHandler : SharpInfoTipHandler
{
    /// <summary>
    /// Gets info for the selected item (SelectedItemPath)
    /// </summary>
    /// <param name="infoType">Type of info to return.</param>
    /// <param name="singleLine">if set to <c>true</c>, put the info in a single line.</param>
    /// <returns>
    /// Specified info for the selected file
    /// </returns>
    protected override string GetInfo(RequestedInfoType infoType, bool singleLine)
    {
        //  Switch on the tip of info we need to provide
        switch (infoType)
        {
            case RequestedInfoType.InfoTip:
 
                //  Format the formatted info tip
                return string.Format(singleLine
                                       ? "{0} - {1} Items"
                                       : "{0}" + Environment.NewLine + "Contains {1} Items",
                                       Path.GetFileName(SelectedItemPath), 
                                       Directory.GetFiles(SelectedItemPath).Length);
 
            case RequestedInfoType.Name:
                
                //  Return the name of the folder
                return string.Format("Folder '{0}'", Path.GetFileName(SelectedItemPath));
                
            default:
 
                //  We won't be asked for anything else, like shortcut paths, 
                //  for folders, so we 
                //  can return an empty string in the default case.
                return string.Empty;
        }
    }
} 

Step 1: Creating the Project

First, create a new C# Class Library project.

Tip: You can use Visual Basic rather than C# - in this article, the source code is C# but the method for creating a Visual Basic Shell Extension is just the same.

In this example, we'll call the project 'FolderInfoTipHandler'. Rename the 'Class1.cs' file to 'FolderInfoTipHandler.cs'.

Now add the following references:

  1. System.Windows.Forms
  2. System.Drawing

These references contain various useful bits and pieces that other parts of the SharpShell library will need, such as icons and context menus.

Tip: If you use Nuget to install SharpShell (see 'Step 2') you don't need to add these references - they'll be added automatically.

Step 2: Referencing SharpShell

We now need to add a reference to the core SharpShell library. You can do that in a few different ways:

Add Reference

Download the 'SharpShell Core Library' zip file at the top of the article and add a reference to the SharpShell.dll file.

Tip: The download on this article is correct at the time of writing - if you need the latest version, use Nuget (as described below) or get the library from sharpshell.codeplex.com.

Use Nuget

If you have Nuget installed, just do a quick search for SharpShell and install it directly - or get the package details at https://www.nuget.org/packages/SharpShell.

Image 2

Use CodePlex

Rather than getting the library from this page, which may not be the latest version, you can always get the very latest version of the library from CodePlex - on the SharpShell home page which is sharpshell.codeplex.com. Nuget will always have the latest stable version - CodePlex may have betas available, and the CodeProject articles will have the version that was available at the time of writing.

Step 3: Deriving from SharpInfoTipHandler

Now we're actually going to create the functionality for the Info Tip Handler. Derive the FolderInfoTipHandler class from SharpInfoTipHandler:

C#
/// <summary>
/// The FolderInfoTip handler is an example SharpInfoTipHandler that provides an info tip
/// for folders that shows the number of items in the folder.
/// </summary>
public class FolderInfoTipHandler : SharpInfoTipHandler
{
} 

SharpInfoTipHandler has only one function you have to override - GetInfo. This function is called to get the info tip. In the MSDN documentation, there are details of other types of information that may be requested via Info Tip Handlers, such as the name of the item, the details of the shortcut (if it's a shortcut to the item) or the details of the item if it's the target of a shortcut. The tip of info requested is in the infoType parameter, and the singleLine parameter will be set to true if the details should be returned on a single line only. Here's how we'd implement this function for our class:

C#
/// <summary>
/// Gets info for the selected item (SelectedItemPath)
/// </summary>
/// <param name="infoType">Type of info to return.</param>
/// <param name="singleLine">if set to <c>true</c>, put the info in a single line.</param>
/// <returns>
/// Specified info for the selected file
/// </returns>
protected override string GetInfo(RequestedInfoType infoType, bool singleLine)
{
    //  Switch on the tip of info we need to provide
    switch (infoType)
    {
        case RequestedInfoType.InfoTip:
 
            //  Format the formatted info tip
            return string.Format(singleLine
                                   ? "{0} - {1} Items"
                                   : "{0}" + Environment.NewLine + "Contains {1} Items",
                                   Path.GetFileName(SelectedItemPath), 
                                   Directory.GetFiles(SelectedItemPath).Length);
 
        case RequestedInfoType.Name:
            
            //  Return the name of the folder
            return string.Format("Folder '{0}'", Path.GetFileName(SelectedItemPath));
            
        default:
 
            //  We won't be asked for anything else, like shortcut paths, for folders, 
            //  so we can return an empty string in the default case.
            return string.Empty;
    }
}

In this simple example, we're only going to provide info for the name of the object and its tooltip.

Tip: The name of the object will not be displayed in the Shell, as far as I know, the value returned when requesting the name via an info tip handler is not used.

Don't forget to avoid newlines if the system requests the tooltip on a single line!

Step 4: Handling the COM Registration

There are just a few things left to do. First, we must add the ComVisible attribute to our class. This because our class is a COM server and must be visible to other code trying to use it.

C#
[ComVisible(true)]
public class FolderInfoTipHandler : SharpInfoTipHandler 

Next, we must give the assembly a strong name. There are ways around this requirement, but generally this is the best approach to take. To do this, right click on the project and choose 'Properties'. Then go to 'Signing'. Choose 'Sign the Assembly', specify 'New' for the key and choose a key name. You can password project the key if you want to, but it is not required:

Image 3

Finally, we need to associate our extension with some types of shell items we want to use it for. We can do that with the COMServerAssociation attribute:

C#
[ComVisible(true)]
[COMServerAssociation(AssociationType.Directory)]
public class FolderInfoTipHandler : SharpInfoTipHandler 

So what have we done here? We've told SharpShell that when registering the server, we want it to be associated with folders in the system.

You can associate with files, folders, classes, drives and more - full documentation on using the association attribute is available on the CodePlex site at COM Server Associations.

We're done! Building the project creates the FolderInfoTipHandler assembly, which can be registered as a COM server to add the extension to the system, adding more detail to the tooltips for folders.

Debugging the Shell Extension

If you have seen any of my other articles on .NET Shell Extensions, you may recognize the 'Server Manager' tool. This is a tool in the SharpShell source code that can be used to help debug Shell Extensions.

Tip: If you want the latest version of the tools, they're available pre-built from the CodePlex site.

Open the Sever Manager tool and use File > Load Server to load the FolderInfoTipHandler.dll file. You can also drag the server into the main window. Selecting the server will show you some details on it. Select the server.

Image 4

Now press 'Test Server' or use 'Server > Test...'. This will open the Test Shell which will simulate the calls that will be made to the server, just as if the Windows Shell was making the calls - however, as this is a managed application, you can quickly attach a debugger to it and see how your server is running. It also lets you test the server without having to install or register it in the system, and this will save you a lot of time (when testing in Explorer for real, you'll be having to restart it lots to unlock the file so you can update it).

Image 5

Installing and Registering the Shell Extension

You can check the 'Installing and Registering the Shell Extension' section of the .NET Shell Extensions - Shell Context Menus for details on how to install and register these extensions - the process is the same.

Useful Resources

Creating Shell Extension Handlers: The main page on MSDN for shell extensions. Very little detail is provided for Info Tip Handlers.

SharpShell on CodePlex: The home of the SharpShell project - includes documentation, discussions and the latest source code and releases.

What's Next?

SharpShell will over time provide a mechanism to create all of the available Shell Extensions using .NET. So far, fully supported are Context Menu Extensions, Icon Handlers and Info Tip Handlers - follow the CodePlex project to stay up to date as new features are added.

History

  • 6th April, 2013: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)