Search code examples
c#registrycontextmenuwindows-10

Register context menu verbs for specific file types


I'm registering extended verbs for all video file types on my system by doing something like this:

        foreach (var ext in FileTypes.VideoTypes)
        {
            var progId = Registry.GetValue($@"HKEY_CLASSES_ROOT\.{ext}", null, null);

            if (progId == null)
            {
                continue;
            }

            Registry.SetValue(
                $@"HKEY_CURRENT_USER\SOFTWARE\Classes\{progId}\shell\dlsub",
                null,
                "Download subtitle");

            Registry.SetValue(
                $@"HKEY_CURRENT_USER\SOFTWARE\Classes\{progId}\shell\dlsub\command",
                null,
                @"""D:\myapp.exe"" ""%1""");
        }

Resulting in something like this (mpeg_auto_file for mkv):

[HKEY_CLASSES_ROOT\mpg_auto_file\shell\dlsub]
@="Download subtitle"

[HKEY_CLASSES_ROOT\mpg_auto_file\shell\dlsub\command]
@="\"D:\\myapp.exe\" \"%1\""

and mplayerc.mp4 for mp4:

[HKEY_CLASSES_ROOT\mplayerc.mp4\shell\dlsub]
@="Download subtitle"

[HKEY_CLASSES_ROOT\mplayerc.mp4\shell\dlsub\command]
@="\"D:\\myapp.exe\" \"%1\""

The problem is that the registered verb shows up for mkv (and a couple of other filetypes), but the context menus for the other file types (like mp4) are unaffected. Adding my verb to HKEY_CLASSES_ROOT\*\shell does work for these filetypes, but this is obviously not what I want!

Any ideas on the difference between these filetypes? Perhaps it has something to do with the registered ProgID (all mplayerc types do not seem to work...).


Solution

  • The default value (aka ProgId) that can be found for specific file extension doesn't always point to correct class (the one that will affect menu entries). During my tests, even on fresh copy of Windows 10 - WMP11.AssocFile.AVI is a ProgId for .avi file extension, however when added entry in WMP11.AssocFile.AVI\Shell\ (either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER) it didn't affect menu at all. I was about to give up but then i found that HKEY_CLASSES_ROOT\.avi\OpenWithProgids store few more values, including WMP11.AssocFile.AVI but also other that starts with word App, i.e. AppX6eg8h5sxqq90pv53845wmnbewywdqq5h. By editing Shell\ for that one, i was able to add menu entry. The downside was - it also affected other file extensions that are somehow linked with AppX6eg8h5sxqq90pv53845wmnbewywdqq5h. I couldn't accept solution that would force me to iterate through all classes found in OpenWithProgids, plus my menu entry had to be shown only for very specific file extensions and not the other. I decided to go with HKEY_CLASSES_ROOT\*\shellex and DLLs that create menu entry dynamically, based on clicked file type (check for extension).