Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Class for Adding Buttons, Menu Items and Explorer Bars to Internet Explorer

0.00/5 (No votes)
19 Feb 2007 1  
A simple class that edits the registry to set up toolbar buttons, menu items and explorer bars for Internet Explorer

Sample Image - CorKatIEExtension.jpg

Menu Items

Sample image

Explorer Bars

Introduction

This is a C# class for the addition of buttons, menu items and explorer bars in Internet Explorer. It should work for Internet Explorer 5 and above, but has only been tested on Internet Explorer 7. It is written as a standalone class and can be referenced by either a Windows Forms application or an ASP.NET application. Included in the source download are two test applications; one for Windows Forms and one for ASP.NET, as well as the full source for the class.

Background

There is a tutorial in the MSDN library for adding these features to your registry. I wanted to create an application to do it so that I wouldn't be searching and editing the registry manually. Also if you build an Explorer toolbar, you could use this class to add the buttons at installation time, rather than rewriting the functionality for each bar you create. The article can be found here and I would recommend reading it to understand what the class does and how it edits your registry.

Using the Code

I have added all the functionality to the InternetExplorerExtender class. To use the class, simply add a reference to the object and instantiate the object.

using CorKat.RegistrySettings;
InternetExplorerExtender iee = new InternetExplorerExtender();

You will also need to reference Microsoft.Win32 to access the RegistryKey class. This enables you to set the root of the registry you wish to enter the settings in, i.e. CurrentUser or LocalMachine.

using Microsoft.Win32;

Class Names

  • CorKat.RegistrySettings.IEEConstants;
  • CorKat.RegistrySettings.IEEenums;
  • CorKat.RegistrySettings.InternetExplorerExtender;

Methods

  • CreateRegistryEntry_MenuItem()
  • CreateRegistryEntry_Button()
  • CreateNewExplorerBar()
  • DeleteKey(string key)
  • DeleteIECache()

Properties

There are many properties. Most have a default value. You will only need to populate certain properties depending on what items you want to add. I have set the object up this way so that you populate the properties before calling the create function and it will use these values to create the registry entries.

An example to add a button using the minimum properties is shown below:

// set the properties
iee.ButtonText = "MyButton";
iee.ApplicationPath = "c:/path/filename.exe";
iee.HotIcon = "c:/path/hoticon.ico";
iee.Icon = "c:/path/icon.ico";

// call the registry creation function for a button
iee.CreateRegistryEntry_Button();

An example to add a menu item using the minimum properties is as follows:

iee.MenuText = "myMenuItem;
iee.ApplicationPath = "c:/path/filename.exe";
// call the registry creation function for a menu item
iee.CreateRegistryEntry_MenuItem();        

The menu is added to the "Tools" menu in Internet Explorer by default. You can also add it to the "Help" menu. To do this, set InternetExplorerExtender.MenuItem to IEEenums.MenuItem.help.

An example to add an Explorer bar using the minimum properties is as shown below:

//set the properties 
iee.MenuText = "MyExplorerBar"; 

// if the explorer bar is a DLL, populate the DLL property. 
//NB if left blank the default is "Shdocvw.dll". this is used for HTML pages
if (txtdll.Text != "") 
    iee.Dll = txtdll.Text;

// if the explorer bar is an HTML page or file, populate the URL property
if (txtURL.Text != "") 
    iee.URL = txtURL.Text; 
iee.CreateNewExplorerBar();

This creates a new item in the view | explorer bar menu and stores the new CLSID in a property. To create a button for the HTML page/DLL immediately after this, call the CreateButton function.

//set the registry paths
iee.BaseRegistryKey = Registry.CurrentUser;
iee.RegistryPath = IEEConstants.Extensions;
iee.TypeOfDetail = IEEenums.DetailType.explorerbar;

// set the properties
iee.ButtonText = "MyButton"
iee.HotIcon = "c:/path/hoticon.ico";
iee.Icon = "c:/path/icon.ico";

// call the registry creation function for a button
iee.CreateRegistryEntry_Button();

There are three core functions for creating the registry entries:

  • CreateRegistryEntry_MenuItem()
  • CreateRegistryEntry_Button()
  • CreateNewExplorerBar()

If you wish to create a toolbar button for the explorer bar, you call the CreateNewExplorerBar() function first. This creates the guid that is stored in the registry for the new explorer bar and stores it in a property for the button registry entry to use. This is the full code for the function:

public void CreateNewExplorerBar()
{
    CreateNewGuid(); //populates AppGuid with a new id
    string SubKey = IEEConstants.ExplorerBarPath + AppGuid;
    //Create a registry entry for the guid
    RegistryKey rk = Registry.ClassesRoot.CreateSubKey(SubKey);
    //set the default value to the name that will appear 
    //in the Internet Explorer menu
    rk.SetValue("", MenuText);

    // create a new sub key for the horizontal or vertical bar
    string impCat = SubKey + "\\Implemented Categories\\";
    if (Vertical)
        impCat += VerticalCatId;
    else
        impCat += HorizontalCatId;

    rk = Registry.ClassesRoot.CreateSubKey(impCat);

    // create a new sub key for InProcServer32
    string inproc = SubKey + "\\InProcServer32";
    rk = Registry.ClassesRoot.CreateSubKey(inproc);
    //set its default value to Shdocvw.dll for an html page or *.dll 
    //for a custom file
    rk.OpenSubKey(inproc);
    rk.SetValue("", Dll);

    //Create a new string value under InProcServer32
    rk.SetValue("ThreadingModel", "Apartment");
    
    // create a new sub key for Instance
    string instance = SubKey + "\\Instance";
    rk = Registry.ClassesRoot.CreateSubKey(instance);
    rk.OpenSubKey(instance);
    //Create a new string value under Instance
    rk.SetValue("CLSID", "{4D5C8C2A-D075-11d0-B416-00C04FB90376}");

    // create a new sub key for Instance
    string InitPropertyBag = instance + "\\InitPropertyBag";
    rk = Registry.ClassesRoot.CreateSubKey(InitPropertyBag);
    rk.OpenSubKey(InitPropertyBag);
    //Create a new string value under Instance
    rk.SetValue("URL", URL); // the html page to open in the explorer bar

    DeleteIECache();

    SubKey = IEEConstants.ExplorerBars + AppGuid;
    //Create a registry entry for the guid
    rk = BaseRegistryKey.CreateSubKey(SubKey);
    // store the BandCLSID for making a button
    BandCLSID = AppGuid;
}

Then you can call the CreateRegistryEntry_Button function:

public void CreateRegistryEntry_Button()
{
    // Create a new id for the button
    CreateNewGuid();
    //set the path to the new registry entry
    //string SubKey = RegistryPath + AppGuid;
    string SubKey = IEEConstants.Extensions + AppGuid;
    //Create the registry entry for the guid
    RegistryKey rk = BaseRegistryKey.CreateSubKey(SubKey);

    //set the default class id used for 3 details.  
    //gets reset if an explorerbar type is used
    string strCLSID = ToolbarExtensionForExecutablesCLSID;

    //create the common registry string values and set them
    rk.SetValue("Default Visible", Visible);
    rk.SetValue("ButtonText", ButtonText);
    rk.SetValue("HotIcon", HotIcon); //path to *.ico file
    rk.SetValue("Icon", Icon); //path to *.ico file

    //CorKat.RegistrySettings.regProperties.
    switch (TypeOfDetail)
    {
        case IEEenums.DetailType.executable:
        {
            rk.SetValue("Exec", ApplicationPath);
            break;
        }
        case IEEenums.DetailType.script:
        {
            rk.SetValue("Script", ApplicationPath);
            break;
        }
        case IEEenums.DetailType.com:
        {
            rk.SetValue("ClsidExtension", ComCLSID);
            break;
        }
        case IEEenums.DetailType.explorerbar:
        {
            strCLSID = ToolbarExtensionForBandsCLSID;
            rk.SetValue("BandCLSID", BandCLSID);
            break;
        }
    }
    //set the class id
    rk.SetValue("CLSID", strCLSID);
}   

The third function creates the menu items. NB: By default the explorer bar registry entry creates a menu item in View | Explorer Bars. This function creates a menu item in either the tools menu (default if nothing is specified) or the help menu.

public void CreateRegistryEntry_MenuItem()
{
    // Create a new id for the menu item
    CreateNewGuid();
    //set the path to the new registry entry
    //string SubKey = RegistryPath + AppGuid;
    string SubKey = IEEConstants.Extensions + AppGuid;
    //Create the registry entry for the guid
    RegistryKey rk = BaseRegistryKey.CreateSubKey(SubKey);
    //create the common registry string values and set them
    rk.SetValue("CLSID", ToolbarExtensionForExecutablesCLSID);
    rk.SetValue("MenuText", MenuText);

    //set the default menu to tools and switch if help is selected
    string strMenu = "tools";
    if (MenuItem == IEEenums.MenuItem.help)
        strMenu = "help";
    rk.SetValue("MenuCustomize", strMenu);

    //create the detailed registry string values and 
    //set them for the application type details
    switch (TypeOfDetail)
    {
        case IEEenums.DetailType.executable:
        {
            rk.SetValue("Exec", ApplicationPath);
            break;
        }
        case IEEenums.DetailType.script:
        {
            rk.SetValue("Script", ApplicationPath);
            break;
        }
        case IEEenums.DetailType.com:
        {
            rk.SetValue("ClsidExtension", ComCLSID);
            break;
        }
        // no case for explorer tool bars as they appear on the 
        // view menu automatically when set up
        // as their set up is different they use a different function
    }
}   

All new entries into the registry require a unique GUID. The function CreateNewGuid caters to this and is called when creating a new explorer bar, button or menu item.

    private string CreateNewGuid()
        {
            AppGuid = Guid.NewGuid().ToString().ToUpper();
            return AppGuid;
        }   

There are three functions used to retrieve registry entries for the button menus and explorer bars. These are used in the Windows example to populate list views for selection and deletion of the entries.

/// Retrieve the subkeys names at the current key.
/// returns a string array
public string[] SubKeyNames()
{
    try
    {
        // Setting
        RegistryKey rk = BaseRegistryKey;
        rk = rk.OpenSubKey(RegistryPath);
        string[] strKeys = rk.GetSubKeyNames();
        return strKeys;
    }
    catch
    {
        return null;
    }
}
/// return an array containing all the sub values of a given key
public string[] SubKeyNames(string key)
{
    try
    {
        RegistryKey rk = BaseRegistryKey;
        RegistryKey regSubKey = rk.OpenSubKey(RegistryPath + "\\" + key);
        string[] strKeys = regSubKey.GetValueNames();
        return strKeys;
    }
    catch
    {
        return null;
    }
}
/// Retrieve the value of the subkeys at the provided subkey key.
public string GetValue(string ValueName, string key)
{
    try
    {
        // Setting
        RegistryKey rk = BaseRegistryKey;
        RegistryKey regSubKey = rk.OpenSubKey(RegistryPath + "\\" + key);
        // If the RegistryKey exists...
        if (regSubKey != null)
            return regSubKey.GetValue(ValueName).ToString();
        else
            return "";
    }
    catch
    {
        return "";
    }
}   

Also there is a function for deleting a key and any subkeys it may have:

public void DeleteKey(string key)
{
    string subkey = RegistryPath + key;
    RegistryKey rk = BaseRegistryKey;

    RegistryKey regSubKey = rk.OpenSubKey(subkey);
    // If the RegistryKey exists, I delete it
    if (regSubKey != null)
        rk.DeleteSubKeyTree(subkey);
}   

The last function DeleteIECache deals with the way Internet Explorer caches the explorer bar menu and needs to be called whenever you create or delete an explorer bar. Otherwise when you open Internet Explorer it will look like nothing has happened due to the fact that it is cached.

public void DeleteIECache()
{
    //delete the registry entry for enums so the 
    //explorer bars aren't cached and the new ones show
    RegistryPath = ComponetCat1Cache;
    RegistryKey rk = BaseRegistryKey;

    RegistryKey regSubKey = rk.OpenSubKey(RegistryPath);
    // If the RegistryKey exists, I delete it
    if (regSubKey != null)
        rk.DeleteSubKeyTree(RegistryPath);

    RegistryPath = ComponetCat2Cache;
    //rk = Registry.CurrentUser;

    regSubKey = rk.OpenSubKey(RegistryPath);
    // If the RegistryKey exists, I delete it
    if (regSubKey != null)
        rk.DeleteSubKeyTree(RegistryPath);
}   

Points of Interest

When you add a new explorer bar by editing the registry, it doesn't show up in the Internet Explorer menu due to the way in which Internet Explorer caches its menus. The MSDN tutorial adding Explorer bars tells you to delete the registry entries:

HKEY_CLASSES_ROOT\Component Categories\{00021493-0000-0000-C000-000000000046}\Enum
HKEY_CLASSES_ROOT\Component Categories\{00021494-0000-0000-C000-000000000046}\Enum

This is the wrong location. You need to delete:

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Discardable\
PostSetup\Component Categories\{00021493-0000-0000-C000-000000000046}\Enum
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Discardable\
PostSetup\Component Categories\{00021494-0000-0000-C000-000000000046}\Enum

However, you don't need to worry about this. Once the new Explorer bar is created, the function will do this for you. However, I have made the function DeleteIECache public so that you can call it if necessary.

History

  • Version 1.0 (initial version) - 22/01/2007
  • Added Visual Studio 2003 zip - 20/02/2007 - N.B. It contains the same class as the Visual Studio 2005 version, but the test app only shows you how to add a button.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here