?

Log in

No account? Create an account

Previous Web | Next Web

So, I just found myself adding a new entry to my Win7 Explorer context menu. Nice and easy one would say. And for the normal "right-click a folder icon" case, it is; setting the command to "d:\path\to\run-program.exe" "%1" and invoking the menu entry does exactly what you would expect; starts "run-program.exe," passing it the right-clicked directory's path.

The problem is that for this particular purpose, it makes sense to have the same entry appear in the context menu that appears when you right-click the empty space between the icons when you are in the folder you want to invoke the menu entry for...

Superficially, this is easy; as well as the Shell key under which the right-click-an-icon context menu entries are defined, HKEY_CLASSES_ROOT entries have a Background\Shell key which defines the right-click-in-the-empty-space context menu entries. So all that needs to be done is to duplicate the structure that is working for the right-click-an-icon context menu under Background\Shell.

As I said, superficially its easy!

However.... although this is enough to make an entry appear in the context menu, trying to invoke the entry results in a rather useless error message:

This file does not have a program associated with it for performing this action. Please install a program
or, if one is already installed, create an association in the Default Programs control panel.

Not very useful or helpful; afterall, I invoked the action using a program association from Explorer!

So what's gone wrong?

Well, after a bit of twiddling around, I've come to a couple of conclusions:

  • Despite being superficially identical to the right-click-an-icon Shell key, Background\Shell is processed differently "under the hood".... don't ask me why though; its a bit weird (or a bug)
  • For Background\Shell (and presumably any other Background\*whatever* entries), the standard "%1" (that's a one, not a lower-case L) parameter placeholder that was inherited from DOS Batch Files simply doesn't work, nor does the alternative "%L" (whether upper- or lowercase) placeholder.
  • What does work is to use the "%V" form (which is tied in to Microsoft's terminology and means "Verb").

In short then, it may be best to try to remember to just use "d:\path\to\run-program.exe" "%V" in any and all command entries that deal with filesystem entities, rather than %1 or "%1"! But be warned: Your mileage may vary.

I should say that that I'm not recommending that without testing first; the "%V" form works perfectly well when invoked from Explorer for single and multiple file selections.


FYI: The placeholder appears to be case insensitive, as both upper- and lowercase "%v" work as expected, HOWEVER, it may be that upper-and lowercase "%L" placeholders are different, as there is mention (see below) of the uppercase ("%L") form being quicker (atleast on 32-bit Windows systems with the 16-bit Windows subsystem available), as it avoids probing for the invoked application's type. It is unclear whether the application type probe occurs on 64-bit versions of Windows that cannot execute Win16 code.


I have no idea why this information is not in the MDSN article itself... :-/ For reference (from a comment by Chris_Guzak against an MSDN page @ archive.org, via superuser.com), the different 'command' parameter placeholders are:


    %* – Replace with all parameters.

    %~ – Replace with all parameters starting with and following the second parameter.

    %0 or 
    %1 – The first file parameter. For example 
         "C:\Users\Eric\Desktop\New Text Document.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 (this is a security best practice)

    % (where  is 2-9) – Replace with the nth parameter.

    %s – Show command.

    %h – Hotkey value.

    %i – IDList stored in a shared memory handle is passed here.

    %l – Long file name form of the first parameter. Note that Win32/64 applications
         will be passed the long file name, whereas Win16 applications get the short
         file name. Specifying %L is preferred as it avoids the need to probe for 
         the application type.

    %d – Desktop absolute parsing name of the first parameter (for items that don't
         have file system paths).

    %v – For verbs that are none implies all. If there is no parameter passed this 
         is the working directory.

    %w – The working directory.

I sort of half-remembered having also seen "%U" used as a placeholder, but after a bit of testing using nircmd's qpop function to output the placeholder values, it appears that this was just plain wrong!! (Although whether it was %U or my memory that was wrong is unknown!! ;-) )