-1

I have created a custom command entry in the registry to add an item to the Windows Explorer context menu when the user right-clicks on a folder. Here is exactly what the value looks like in the registry:

"C:\Program Files\Directory Switcher\DirectorySwitcher.exe" "%V" "2021.0"

%V returns the current directory. If the directory path has any folders with spaces in the name it causes the path to split into additional command line arguments. To get around this, Microsoft tells you put quotes around it "%V".

The specific issue is that when %V is at the drive root, the backslash in C:\ escapes the end quote and causes the rest of the command line parameters to be parsed incorrectly. For example, at C:\ I get a single argument C:" 2021.0 rather than the expected two of C:\ and 2021.0.

How do I properly encapsulate %V so that it works for normal folder paths and drive roots that end with a backslash? The alternative is to change my program to look for this edge case but I would rather understand how to correct my shell verbs.

(Information about %V can be found at this SuperUser question)

Official Microsoft documentation about shell command strings can be found here

Bill Casey
  • 111
  • 1
  • 6
  • What programming language? Code of the exe parsing the args? I expect the problem in the executable. – Thomas Weller Sep 03 '21 at 21:33
  • Can you provide a [mre]? Which regitry entry is it? – Thomas Weller Sep 03 '21 at 21:35
  • This is in C# and I have a good idea of how to handle this edge-case in the executable itself but it would require rewriting the Main method. This is because the program has different control flow depending on whether it has 0, 1, or 2 command line arguments. – Bill Casey Sep 03 '21 at 21:39
  • @ThomasWeller this is a custom registry entry that I made following some of the answers as outlined in [this SO question](https://stackoverflow.com/a/29769228/9777335) . I am confident the issue is with how the text of the registry command is being parsed because the application does start successfully through the context menu. – Bill Casey Sep 03 '21 at 21:46
  • @ThomasWeller apologies, the context menu entry I made is actually a parent menu that has sub commands in it. The process I followed was described [here](https://blog.sverrirs.com/2014/05/creating-cascading-menu-items-in.html) This [official microsoft documentation](https://learn.microsoft.com/en-us/windows/win32/shell/context-menu-handlers#creating-cascading-menus-with-the-subcommands-registry-entry) also describes the cascading that I am using. – Bill Casey Sep 03 '21 at 21:59
  • Is %V even documented as something you can use or is it a private Microsoft value? – Anders Sep 04 '21 at 12:14
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. – Community Sep 09 '21 at 18:42

1 Answers1

0

If your program can deal with relative paths, I would enter

"%V\a\.."

resulting in

X:\\a\..

for a root drive, but C# can handle the double backslash.

The idea is: go into a (nonexisting) directory and back up again.

"%V\."

might even be better and shorter.

Thomas Weller
  • 55,411
  • 20
  • 125
  • 222
  • It does not support relative paths at the moment, but that is a potential solution. – Bill Casey Sep 03 '21 at 22:11
  • @BillCasey: it seems adding `\.` also works – Thomas Weller Sep 03 '21 at 22:16
  • 1
    the `\.` worked for me with only minimal modifications to my code. – Bill Casey Sep 03 '21 at 22:25
  • There doesn't appear to be a surefire way to get around this issue without changing project code. A second potential solution which is to swap the argument positions and make the directory last. You can also add a project specific sentinel character like this: `"2021.0" "%V *"` and then just parse accordingly. Adding an additional space will just cause it to get trimmed. Inside of my program I can look to strip out the trailing space and asterisk from the path and this prevents the backslash in C:\ from escaping anything. – Bill Casey Sep 07 '21 at 15:03
  • I really wonder what your code does with that path. If it were just plugged into a FileInfo or DirectoryInfo, stuff should be good. If your code is doing string manipulation, it probably was never correct before, you just didn't notice. In which case would `\.` not work well? – Thomas Weller Sep 07 '21 at 15:20
  • This is a specialized tool made to open a corresponding folder in a split repository structure. Assume project 'x' solution file is in C:/product/source/a/b/c/d/x and it's binaries are published to C:/product/publish/a/b/c/d/x. The split paths are not always this straight forward and there are a few known 'pivot' directories. I do repeated string substitutions and check 'guesses' using Directory.Exists(). It was working fine before but I had to add some functionality based on user feedback and that is how I discovered the drive folder root bug. – Bill Casey Sep 07 '21 at 15:45
  • If you have `string path = args[0];` before, you can have `string path = Path.GetDirectoryName(args[0]);` now. If there's anything else to do, it's not related to the Registry thing. – Thomas Weller Sep 07 '21 at 22:58