PowerShell 6.1.0 (preview) messes verbs of directories, causing Previous Versions to open previous verions of a directory in PowerShell

Updated on 4 October: Pull request #6799 addresses the issue on the open verb.

Story

Issue #6799 in PowerShell repository on GitHub raises the question why Previous Versions is opening previous versions of a directory in PowerShell, instead of File Explorer as expected. The reason is that PowerShell 6.1.0 (preview) installer creates a context menu to open the shell on any folder. However, it unfortunately names the verbs as open/runas, which is very dangerous since they are canonical and do not make much sense for a folder. Related is issue #7815, where shortcuts to a folder are opened in PowerShell.

Issue

Condition

  1. You install PowerShell 6.1.0 (preview) x64 MSI installer and install it on Windows 10 x64.
  2. You open the ‘Properties’ dialog of a folder, go to the ‘Previous Versions’ tab, select a previous version and click ‘Open’.

Symptoms

A PowerShell 6.1.0 is spawned with current location set to the previous version folder.

Expected behaviours

A File Explorer window is spawned to view the previous version of this folder.

Workaround

Workaround 1

Proposed by Christoph Bergmeister [MVP] (@bergmeister) in this thread: Uninstall PowerShell 6.1.0 (preview) and reinstall it without adding the context menu.

Workaround 2

Propsed by me in this thread: Manually change the name of HKCR\Directory\ContextMenus\PowerShell6x64\open to openpwsh.

Details

In this section, I will provide a minimal reproduction of the issue for observation.

Reproduction

  1. Make sure your machine does not have PowerShell 6.1.0 installed.
  2. Create and log in to a new local standard user account. If you cannot create a new account, it is okay to test this in your own account (all changes can be reversed).
  3. Download this registry file and merge it into the registry.
  4. Download this C++ code and compile it with Visual Studio 2017. This piece of code is adapted from Simple things you can do with the ShellExecuteEx function by Raymond Chen.
  5. Run shexe open C:\Windows from Command Prompt, you will see the Windows folder opened in File Explorer.
  6. Run shexe open C:\Windows x, you will see a new Command Prompt window.
  7. Run shexe "" C:\Windows, you will see the Windows folder opened in File Explorer.
  8. Run shexe "" C:\Windows x, you will see the Windows folder opened in File Explorer.
  9. Open the ‘Properties’ dialog of a folder with a previous version, go to the ‘Previous Versions’ tab, select a previous version and click ‘Open’, you will see a new Command Prompt window.
  10. Download this registry file and merge it into the registry. This action reverses step 3.

Summary

Step 5, 6, 7 and 8 tries the following combinations of ShellExecuteEx settings:

Verb →
IContextMenu
open (no verb)
No 5 7
Yes 6 8

If we use IContextMenu, the cascaded menu verbs are found and are possible candidates. If we do not use it, we only have the static verbs, which are <class>\shell\<verb>.

Since our cascaded test menu has a verb named open, and is set in the user key, it is surely to be resolved after the machine key is searched. For C:\Windows, the classes searched include Folder and Directory. Normally, the open verb is provided by HKLM\SOFTWARE\Classes\Folder\shell\open. However, since our verb is found later than the system-provided one, it overrides it when referred to by name.

If we do not provide a verb, according to the documentation, the system first tries using a default verb. Here comes some curiosity. Folder class has no default verb, and Directory class has none as the default verb. The system thinks there is no default verb. It then tries using open verb. However, in this case, it uses the open verb found in Folder.

The verb explore expands the tree view to the folder, which is not the case. Therefore, the verb is open. My assumption: if lpVerb is nullptr and the system decides there is no default verb, the function will keep track of the first encountered verb as well as the first encountered open verb.

The none value is not special, if we set the default value of Folder\shell to none, shexe "" C:\Windows will fail. However, if we do not set that value, and set Directory\shell to Powershell (some actual existent verb), then shexe "" C:\Windows will use that verb. Furthermore, if we run shexe "" C:\Windows x (use IContextMenu with nullptr verb) with Directory\shell defaults to Powershell, the selected verb on my machine is AnyCode, which is Visual Studio. The behaviour is also observed in File Explorer context menu.

I suspect there is some mess in ShellExecuteEx verb resolving?

I am pretty much sure that the ‘Open’ button in ‘Previous Versions’ tab uses open verb with IContextMenu enabled.

Solution

Microsoft should rename its ‘Open in PowerShell’ verbs as openpwsh and runaspwsh, to avoid name collision.

Note that the name runaspwsh does not automatically provide the elevation prompt, therefore the command must be changed to use a launcher, and it cannot use pwsh.exe itself (even with -WindowStyle Hidden) or there will be a console flashing before the real console is opened.

Although the runas verb is not taken for folders/directories, Microsoft should not assume it. Since any interactive command interpreter might want to have the ability to ‘Run as Administrator’, it is unfair for any of them to occupy the verb. All interpreters (that are not the most awesome) should use a launcher for this purpose.

To prevent future naughty programs from causing this problem, ‘Previous Verions’ should disable IContextMenu handling for Windows versions known to have a static verb for folders/directories, so that the hope of finding the Windows-defined open verb is larger.

Moral

Be careful when you register a verb for a file type. If you are registering a new file type, you can safely use canonical verbs. However, if you are merely extending an existing file type, you might want to decorate the verb with your product name.

Please enable JavaScript to view the comments powered by Disqus.