In general, HKEY_CLASSES_ROOT is intended to be read from but not written to, although one can write to it.
- The
HKEY_CLASSES_ROOT
subtree is a view formed by merging HKEY_CURRENT_USER\Software\Classes
+ file type registration visible to the current user onlyHKEY_LOCAL_MACHINE\Software\Classes
+ globally register a file type on a particular computer
- There are two main approaches:
- One id to extend the context menu defined by the selected default program (ProgID)
- The Other is to extend the context menu based on System file Extension Association *"ClassesKey"* :code:`SystemFileAssociations`
The (ProgID) defined verbs have priority over the same ones defined in :code:`...SystemFileAssociations` , but are dependent on that particular Application, When that application uninstalls, it would normally delete its registry entry, along with what modifications/additions you may have done under that key. Or if the default (ProgID) is changed, your modifications will no longer be in effect.
The :code:`...SystemFileAssociations` registrations are stable even when users change/uninstall the default programs.
run
-> regedit
- Navigate to one of the flowwing Classes Key (Folders) + HKEY_CLASSES_ROOT + HKEY_CURRENT_USERSoftwareClasses + HKEY_LOCAL_MACHINESoftwareClasses
(ProgID) Method: - Find the Extension specific Handler Class, e.g. .xls
\Computer\HKEY_CLASSES_ROOT\.xls\
- [String Value] Name:"
(Default)
" Data:"ExcelViewer.Sheet.8
"
- Find the Handler Class (ProgID) context Menu Definition
\Computer\HKEY_CLASSES_ROOT\ExcelViewer.Sheet.8\shell\
- Navigate to the :code:`shell` subkey
\Computer\HKEY_CLASSES_ROOT\ExcelViewer.Sheet.8\shell\
:code:`...SystemFileAssociations` Method
- Navigate to :code:`HKEY_CURRENT_USERSoftwareClassesSystemFileAssociations`
- locate :code:`.oxps` key , if it doesnt exist, create it (right click --> New --> Key)
- locate :code:`shell` subkey, if it doesn't exist, create it
- Within the
\shell\` key there will be a [String Value] Name:":code:`(Default)
" Data:"View
" + This is the Key Name which is used by default. There will be a subkey with this very name (View in this case) + Used when you double click shown as the bold option in the context menu. - Define the context Menu, additional keys
- Within the shell folder there are other folders named keys.
Each has a String Value Named :"
(Default)
" with the Value of the text that should appear in the context menu. e.g. Data:"&View
" + The Ampersand & is to provide a shortcut letter to this menu item amoung the other one that may be on the list. The ampersand can be placed anywhere in the text and the letter the Ampersand is infront of will define that shortcut letter.- When you press that letter with the context menu open it will execute that command unless there are more than one menu item with the same assigned letter. * In this case the selected item will cycle between the different menu items that have that same shortcut key. You can then execute the command by pressing spacebar or enter.
Within each unique shell folder named key there will be a subkey (folder) named "command
" which will contain a String Value Named: "(Default)
" with the value of the command to execute when this menu item is selected and executed.
e.g. :code:`C:Prog.........xlview.exe "%1" `
- The Percentage is passing the first argument to the program in this case the selected file name.
The command which can be run accepts several percent Arguments.
Parameter | example | description |
---|---|---|
%0 |
C:\tmp\fn.ext |
Long File Path |
%1 |
C:\tmp\fn.ext |
Long File Path |
%D |
C:\tmp\fn.ext |
Long File Path |
%H |
0 |
? |
%I |
:2113706496:3816 |
? |
%L |
C:\tmp\fn.ext |
Long File Path |
%S |
1 |
? |
%U |
:code:` ` | blank |
%V |
C:\tmp\fn.ext |
Long File Path |
%W |
C:\tmp |
Long Parent Folder Path |
- Any
%~f1
style modifiers are not interpreted!- Observed in existing command strings
%1
and%L
are mostly used.%2
or%*
are blank, even if multiple files are selected.- When multiple files are selected and the command is executed, multiple instances of the command are executed.
Of interest I would consider %1,%L,%W
, but there is not much you can program into your command line with these arguments.
To take advantage of %~f1
style modifiers, a work around is to create a *BATCH* file.
- The context menu item will call the batch parameter passing it
%1
or%L
which contains all the info you can get anyhow.- The Batch file will call the command of interest.
In the command subfolder of the context menu item:
- set the
(Default)
String value to"C:\opt\bin\mybatfile.bat" "%1"
- call the command of interest from within the batch file:
+
"C:\opt\ImageMagick\convert.exe" "%1" -normalize %~dpn1_n%~x1
Here is a list of %~
style modifiers
Expression | Result |
---|---|
%~1 |
Removes surrounding quotes ("). |
%~f1 |
Fully qualified pathname. |
%~d1 |
Drive letter only. |
%~p1 |
Path only. |
%~n1 |
Filename only. |
%~x1 |
File extension only. |
%~s1 |
Short DOS 8.3 file and path. |
%~a1 |
File attributes. |
%~t1 |
Modification date/time of file. |
%~z1 |
Length of file in bytes. |
%~$PATH:1 |
Long Path of First filename with extension match in Path. |
- When an absolute reference e.g.
c:\tmp\a.txt
is provided as argument then the parent directories and drive letters are extracted from this path.- When a relative reference e.g.
a.txt
is provided then the current working directory and drive are used.- these can be combined e.g.
%~dpn1_n%~x1
appends_n
to the filename conserving the original filename and extension.
You can disable a key by
- Deleting the key and the associated subkey
- Inserting a String Value with the Name:"LegacyDisable" +
LegacyDisable REG_SZ ""
- Inserting a String Value with the Name:"Extended" +
Extended REG_SZ ""
+ In this case you are not actually disabling the command but rather placing it in the extended Context Menu list which is opened when *holding down the shift key* while opening the context menu.
Single Item:
Shell (Default) REG_SZ (value not set) cmd1 (Default) REG_SZ <Display String> command (Default) REG_SZ <command string>
Sub Menu Items:
Shell (Default) REG_SZ (value not set) SubMenuGroup (Default) REG_SZ (value not set) MUIVerb REG_SZ <SubMenu Display String> SubCommands REG_SZ "" Shell (Default) REG_SZ (value not set) cmd1 (Default) REG_SZ <Display String> command (Default) REG_SZ <command string> cmd2 (Default) REG_SZ <Display String> CommandFlags REG_DWORD <display flags> command (Default) REG_SZ <command string>
The command flags are optional and some interesting ones could be:
Flag | Value | Description |
---|---|---|
ECF_DEFAULT | 0x00 | No Flags Set |
ECF_HASLUASHIELD | 0x10 | Display UAC Icon |
ECF_SEPARATORBEFORE | 0x20 | Separator before Item |
ECF_SEPARATORAFTER | 0x40 | Seperator after Item |
If you want more than one flag, it is just the sum of the flags to apply.
CommandFlags REG_DWORD 0x60
would be a seperator before and after the item.
The context Menu Handlers open a seperate instance of the defined command for all selected files when the command is selected.
To pass all selected files to a single command there are basically two options:
- Handle active instances of the command with IPC (inter process communication) and collect the multiple files passed onto a single command with some sort of timeout.
- Use the SendTo context menu section, which passes all selected files as arguments to the single command.
To access the SendTo section in an explorer type shell:sendto
and the Folder containing the sendto commands will open.
Within there one could creat a BAT ch file for handling the multiple arguments just as previously described.
- To handle more than 9 files use the
%*
operator
- Note that this operator is not compatible with the
%~
style modifiers- It will list all arguments as absolute paths to the selected files.
example:
convert %* -normalize -quality 36 -background white -page a4 %~n1.pdf
While debugging I have found very helpful to use
cmd.exe /k echo <command of context menu item>
This opens a command window and keeps it open so that you can see what is being actually passed to the command line.
"C:\opt\bin\imgmgkcnv.bat" "%1" _p25 "-resize 25%% "
"C:\opt\ImageMagick\convert.exe" %1 %~3 %~dpn1%2%~x1
- https://viswaug.wordpress.com/2007/09/25/using-modifiers-with-parameters-in-batch-files/
- http://www.nirsoft.net/utils/shell_menu_view.html
- http://www.nirsoft.net/utils/shexview.html
- https://web.archive.org/web/20180120021145/https://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/percent.mspx?mfr=true
- https://docs.microsoft.com/en-us/windows/desktop/api/shobjidl_core/nf-shobjidl_core-iexplorercommand-getflags
- https://www.winhelponline.com/blog/cascading-menu-jump-lists-issue-windows-10/
- https://en.wikibooks.org/wiki/Windows_Batch_Scripting
- http://www.robvanderwoude.com/ntstart.php
- https://www.howtogeek.com/howto/windows-vista/how-to-clean-up-your-messy-windows-context-menu/
- https://stackoverflow.com/questions/2123762/add-menu-item-to-windows-context-menu-only-for-specific-filetype
- https://docs.microsoft.com/en-us/windows/desktop/shell/how-to-exclude-an-application-from-the-open-with-dialog-box-for-unassociated-file-types
- https://docs.microsoft.com/en-us/windows/win32/shell/fa-file-types
- https://docs.microsoft.com/en-us/windows/win32/shell/fa-sample-scenarios
- https://docs.microsoft.com/en-us/windows/win32/shell/default-programs
- https://docs.microsoft.com/en-us/windows/win32/shell/app-registration
- https://docs.microsoft.com/en-us/windows/win32/shell/launch
- https://stackoverflow.com/questions/2123762/add-menu-item-to-windows-context-menu-only-for-specific-filetype