After creating a rather useful command-line application the other day I wanted to expose it in a user friendly way through Windows Explorer.
So after a lot of trial and error I finally managed to create what I wanted to see:
- Cascading menu with sub items and keyboard shortcuts
- Consistent ordering of menu items
- Separator to divide the main action from the two sub actions
- Menu only visible for certain types of files (in this case *.ini files)
- Menu items execute my program via the shell command line
But first, the complete registry code
[HKEY_CLASSES_ROOT\SystemFileAssociations\.ini] [HKEY_CLASSES_ROOT\SystemFileAssociations\.ini\shell] [HKEY_CLASSES_ROOT\SystemFileAssociations\.ini\shell\myactiontoplevel] "MUIVerb"="My &Tool" "subcommands"="" [HKEY_CLASSES_ROOT\SystemFileAssociations\.ini\shell\myactiontoplevel\shell] [HKEY_CLASSES_ROOT\SystemFileAssociations\.ini\shell\myactiontoplevel\shell\a_myactionmain] @="My Main &Action" "CommandFlags"=dword:00000040 [HKEY_CLASSES_ROOT\SystemFileAssociations\.ini\shell\myactiontoplevel\shell\a_myactionmain\command] @="C:\\tool\\mine.exe -i \"%1\"" [HKEY_CLASSES_ROOT\SystemFileAssociations\.ini\shell\myactiontoplevel\shell\b_myactionfirst] @="My Action &One" [HKEY_CLASSES_ROOT\SystemFileAssociations\.ini\shell\myactiontoplevel\shell\b_myactionfirst\command] @="C:\\tool\\mine.exe -i \"%1\" -first" [HKEY_CLASSES_ROOT\SystemFileAssociations\.ini\shell\myactiontoplevel\shell\c_myactionsecond] @="My Action &Two" [HKEY_CLASSES_ROOT\SystemFileAssociations\.ini\shell\myactiontoplevel\shell\c_myactionsecond\command] @="C:\\tool\\mine.exe -i \"%1\" -second -debug"
1) The Cascading menu
The name of the key (
myactiontoplevel) must be unique and ideally not conflict with other values.
The top level menu must have the string entry
subcommands with no text in it. Otherwise none of the child menus will show in Explorer as nested.
MUIVerb value controls the text displayed for the menu item (it is also possible to skip this and just use the "default" entry for the registry key. The ampersand (&) defines the shortcut key character (will be underlined when applicable).
All nested commands sit under the
\shell\ sub-key defined for the top level menu entry.
2) Consistent ordering
Windows sorts the sub menu items according to their key name (e.g. myactionfirst, myactionsecond). Therefore to ensure the correct ordering of the sub items I prefix them with a sorting character to ensure consistent sorting. The image below shows an example of what happens to the menu items if the sorting prefix is skipped in the code above.
CommandFlags <dword> entry can be added to instruct Windows to add a separator menu entry. The value is of type
EXPCMDFLAGS. To control the placement of the separator use either
0x40 (separator below) or
0x20 (separator above).
Following values are supported, sum to combine features
|0x08||Entry is a separator. Consecutive separators are collapsed into a single separator|
|0x10||Shows a UAC shield next to the menu item|
|0x20||Show a separator above this item|
|0x40||Show a separator below this item|
4) Showing menu item only for *.ini files
To enable the menu item only for ini files.,the root
\shell\ entry can be placed either under
HKEY_CLASSES_ROOT\SystemFileAssociations\.ini (as shown above) or under
There is not a clear distinction between which of these keys is better placement for your custom entry. The
\inifile\ entry should already have some shell keys defined by default and these commands seem to be placed before the
\SystemFileAssociations\.ini entries in the menu.
Otherwise I have not noticed any other difference than that.
Do not place the registry entries under
HKEY_CLASSES_ROOT\.ini as this location is only used to map to
HKEY_CLASSES_ROOT\inifile (as evident by the default value). If you place any \shell\ entries under
HKEY_CLASSES_ROOT<b>\</b>.ini they will not show up.
5) Executing a custom application
This one is relatively easy to do as you only need to point the
\command\ key to the location of your executable and then place any parameters you want in the command line. By default the
%0 contain the selected file path (make sure you place all
%1 type of variables in quotes).
Other % macros are:
||the first file parameter. For example “C:\docs\supersecret\world.txt”. Generally this should be in quotes and the applications command line parsing should accept quotes to disambiguate files with spaces in the name and different command line parameters. Just note that if the path is not a file but a directory path then the trailing backslash will not be included, e.g. C:\docs\ will be C:\docs|
||(where N is 2 - 9), replace with the nth parameter|
||hotkey value (number, 0 if not set)|
||IDList stored in a shared memory handle is passed here. Example ":1084009376:4272"|
||long file name form of the first parameter. Note win32 applications will be passed the long file name, win16 applications get the short file name. Specifying
||desktop absolute parsing name of the first parameter (for items that don’t have file system paths)|
||for verbs that are none implies all, if there is no parameter passed this is the working directory or the file path.|
||the working directory|
Explicitly about creating entries in right-click menus on the Desktop and the My Computer Icon.
Links to various other types of menus that can be customized
Developer & Programmer with +15 years professional experience building software.
Seeking WFH, remoting or freelance opportunities.