2011-05-22

Cascading context menus via static registry entries and ExtendedSubCommandsKey in Windows 7

The Problem

If you have been looking for a way to add cascading menus to the Windows 7 Explorer using static registry entries you may have found this article on MSDN. It is either too obscure to understand or wrong, or both, at least in the version dated 5/3/2011.

The description below was derived from looking at what registry accesses Explorer performs when you open a context menu (using MS / Sysinternals Process Explorer).

The Solution

First you create an “anchor” entry that will be added to the context menu:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\*\shell\myusefultools_anchor]
"MUIVerb"="My Useful Tools"
"ExtendedSubCommandsKey"="*\\ContextMenus\\myusefultools"

If ExtendedSubCommandsKey is set to “foo\bar” then Explorer will look for the key “HKEY_CLASSES_ROOT\foo\bar\Shell”. Under that key it expects one subkey for each entry, e.g. (using the above value for ExtendedSubCommandsKey):

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\*\ContextMenus\myusefultools\Shell\001cmdhere]
"MUIVerb"="Open CMD here"

[HKEY_CLASSES_ROOT\*\ContextMenus\myusefultools\Shell\001cmdhere\command]
@="cmd.exe"

[HKEY_CLASSES_ROOT\*\ContextMenus\myusefultools\Shell\010morecmd]
"MUIVerb"="Another Command"

[HKEY_CLASSES_ROOT\*\ContextMenus\myusefultools\Shell\010morecmd\command]
@="cmd.exe"

Random stuff

Add "Position"="Bottom" to the anchor entry if you want it to show up at the bottom of the context menu.

The submenu entries are sorted according to the name of their registry key. I added 0XX to the names to force a specific order. As described in the MSDN article the CommandFlags value can be added (using the codes listed here) to customize the menu entries and create separators.

[HKEY_CLASSES_ROOT\*\ContextMenus\myusefultools\Shell\005separator]
"CommandFlags"=dword:00000008

5 comments:

  1. this quite makes up for the poor documentation on msdn. however, i haven't managed to get this working for a specific file type - only for *

    any ideas if it's possible?

    ReplyDelete
  2. @idleberg
    Sorry I haven't tried that, so I don't know. If it doesn't work you could use the Process Explorer to see what registry entry it looks at.

    ReplyDelete
  3. Thanks for this, a lot clearer than the MS docs.
    I've managed to extract icons from dlls containing resources like this:
    "Icon"="c:\\location\\mydll.dll,0"
    Is there a way to also extract texts for the items from a dll resource? I'm looking at a situation where I need a localized menu text ...

    ReplyDelete
  4. If you want a icon in the submenu, put this after MUIVerb:
    "icon"="C:\\xxx\\yyy.exe"

    ReplyDelete