GeezerVison is showing github.com — Fix: Use %1 instead of %V! for folder context menu paths by tekintian · Pull Request #26718 · PowerShell/PowerShell
Conversation
- Changed %V! to %1 in both openpwsh\command and runas\command registry keys
- %V! returns background path (current folder), while %1 returns selected item path
- Fixes issue where right-clicking a subfolder would open parent folder instead
- Aligns with PowerShell file context menu which already uses %1 correctly
- Resolves network drive path issues in Windows VM shared directories
Fix: Correct folder path resolution in Explorer context menu for network drives
Problem Description
When using PowerShell installed in a Windows VM with shared directories from the host (e.g., Z:\ mapped to \\Mac\work), right-clicking on a subfolder and selecting "Open here as Administrator" would:
- Show an error:
Set-Location: Cannot find drive. A drive with the name 'Z' does not exist.
- Open the parent folder instead of the selected subfolder
Example: Right-clicking Z:\projects\electron\double-mouse-downloader would open Z:\projects\electron instead of the selected folder.
Root Cause
The Explorer context menu registry entries were using %V! placeholder, which returns the background path (current folder) rather than the selected item path.
%V! = background path (where right-click was invoked)
%1 = selected item path (the actual folder/file clicked)
This caused the context menu to always use the parent folder path, regardless of which subfolder was actually selected.
Solution
Changed both folder context menu entries in assets/wix/Product.wxs from %V! to %1:
- Line 458:
openpwsh\command - Normal PowerShell launch
- Line 466:
runas\command - Elevated PowerShell launch (Administrator)
This aligns with the PowerShell file context menu (line 477) which already correctly uses '%1' for the selected file path.
Changes Made
- Modified:
assets/wix/Product.wxs
- Changed: 2 occurrences of
%V! → %1
- No functional changes to the PowerShell launch behavior, just correct path resolution
Testing
- Verified that right-clicking a subfolder now correctly opens that specific folder
- Network drive paths (e.g.,
Z:\) now work correctly in elevated PowerShell sessions
- The error about missing drive Z: no longer appears
Related Issue
This fixes the issue described in the bug report where users couldn't directly operate on folders in Windows VM shared directories.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
- Changed %V! to %1 in both openpwsh\command and runas\command registry keys
- %V! returns background path (current folder), while %1 returns selected item path
- Fixes issue where right-clicking a subfolder would open parent folder instead
- Aligns with PowerShell file context menu which already uses %1 correctly
- Resolves network drive path issues in Windows VM shared directories
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ! in %V! is a dummy character paired with -RemoveWorkingDirectoryTrailingCharacter — together they avoid a \" escaping issue on root paths (#8287). Removing the ! means the switch will strip the last real character of the path instead (e.g., C:\Users → C:\User).
Background
When a path like C:\ is quoted on the Windows command line, the trailing \" is interpreted as an escaped quote rather than the end of the string (see #8278). PR #8287 introduced a workaround: append a dummy ! to the path and use -RemoveWorkingDirectoryTrailingCharacter to strip it:
pwsh -RemoveWorkingDirectoryTrailingCharacter -WorkingDirectory "C:\!"
# "C:\!" → no escaping issue → strip "!" → "C:\"
The problem with this PR
This PR changes %V! to %1, removing the ! but keeping -RemoveWorkingDirectoryTrailingCharacter. This causes two issues:
- Non-root paths: the last real character is stripped (
C:\Users → C:\User)
- Root paths: the
\" escaping issue returns ("C:\" → broken command line)
I verified this locally:
| Input |
Result |
pwsh -RemoveWorkingDirectoryTrailingCharacter -WorkingDirectory "C:\Users!" |
C:\Users ✅ |
pwsh -RemoveWorkingDirectoryTrailingCharacter -WorkingDirectory "C:\Users" |
falls back to default ❌ |
pwsh -RemoveWorkingDirectoryTrailingCharacter -WorkingDirectory "C:\!" |
C:\ ✅ |
pwsh -RemoveWorkingDirectoryTrailingCharacter -WorkingDirectory "C:\" |
falls back to default ❌ |
Suggested fix
If %1 is the correct variable for the cascading context menu, just preserve the sentinel !. See the inline suggestions below.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
|
</RegistryKey>
|
|
|
<RegistryKey Root="HKCR" Key="Directory\ContextMenus\$(var.ProductName)$(var.SimpleProductVersion)$(sys.BUILDARCH)\shell\openpwsh\command">
|
|
|
<RegistryValue Type="string" Value="[VersionFolder]pwsh.exe -NoExit -RemoveWorkingDirectoryTrailingCharacter -WorkingDirectory "%V!" -Command "$host.UI.RawUI.WindowTitle = '$(var.ProductName) $(var.SimpleProductVersion) ($(sys.BUILDARCH))'""/>
|
|
|
<RegistryValue Type="string" Value="[VersionFolder]pwsh.exe -NoExit -RemoveWorkingDirectoryTrailingCharacter -WorkingDirectory "%1" -Command "$host.UI.RawUI.WindowTitle = '$(var.ProductName) $(var.SimpleProductVersion) ($(sys.BUILDARCH))'""/>
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
<RegistryValue Type="string" Value="[VersionFolder]pwsh.exe -NoExit -RemoveWorkingDirectoryTrailingCharacter -WorkingDirectory "%1" -Command "$host.UI.RawUI.WindowTitle = '$(var.ProductName) $(var.SimpleProductVersion) ($(sys.BUILDARCH))'""/> |
|
<RegistryValue Type="string" Value="[VersionFolder]pwsh.exe -NoExit -RemoveWorkingDirectoryTrailingCharacter -WorkingDirectory "%1!" -Command "$host.UI.RawUI.WindowTitle = '$(var.ProductName) $(var.SimpleProductVersion) ($(sys.BUILDARCH))'""/> |
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have reviewed the code changes and agree with yotsuda's analysis. The PR correctly identifies that %1 should be used for the selected item path instead of %V!, but removing the trailing sentinel character ! while keeping -RemoveWorkingDirectoryTrailingCharacter will cause the issues yotsuda described. The suggested fix to use %1! maintains both the correct path variable and the workaround for the escaping issue from #8287.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
|
</RegistryKey>
|
|
|
<RegistryKey Root="HKCR" Key="Directory\ContextMenus\$(var.ProductName)$(var.SimpleProductVersion)$(sys.BUILDARCH)\shell\runas\command">
|
|
|
<RegistryValue Type="string" Value="[VersionFolder]pwsh.exe -NoExit -RemoveWorkingDirectoryTrailingCharacter -WorkingDirectory "%V!" -Command "$host.UI.RawUI.WindowTitle = '$(var.ProductName) $(var.SimpleProductVersion) ($(sys.BUILDARCH))'""/>
|
|
|
<RegistryValue Type="string" Value="[VersionFolder]pwsh.exe -NoExit -RemoveWorkingDirectoryTrailingCharacter -WorkingDirectory "%1" -Command "$host.UI.RawUI.WindowTitle = '$(var.ProductName) $(var.SimpleProductVersion) ($(sys.BUILDARCH))'""/>
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
<RegistryValue Type="string" Value="[VersionFolder]pwsh.exe -NoExit -RemoveWorkingDirectoryTrailingCharacter -WorkingDirectory "%1" -Command "$host.UI.RawUI.WindowTitle = '$(var.ProductName) $(var.SimpleProductVersion) ($(sys.BUILDARCH))'""/> |
|
<RegistryValue Type="string" Value="[VersionFolder]pwsh.exe -NoExit -RemoveWorkingDirectoryTrailingCharacter -WorkingDirectory "%1!" -Command "$host.UI.RawUI.WindowTitle = '$(var.ProductName) $(var.SimpleProductVersion) ($(sys.BUILDARCH))'""/> |
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. The same issue applies here for the elevated (runas) context menu entry. Using %1! instead of %1 ensures proper path handling.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PR correctly identifies the issue with using %V! vs %1, but as yotsuda pointed out, the trailing ! character must be preserved to work with -RemoveWorkingDirectoryTrailingCharacter. Please update both lines to use %1! instead of %1 to maintain the workaround for the escaping issue from #8287.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
|
</RegistryKey>
|
|
|
<RegistryKey Root="HKCR" Key="Directory\ContextMenus\$(var.ProductName)$(var.SimpleProductVersion)$(sys.BUILDARCH)\shell\openpwsh\command">
|
|
|
<RegistryValue Type="string" Value="[VersionFolder]pwsh.exe -NoExit -RemoveWorkingDirectoryTrailingCharacter -WorkingDirectory "%V!" -Command "$host.UI.RawUI.WindowTitle = '$(var.ProductName) $(var.SimpleProductVersion) ($(sys.BUILDARCH))'""/>
|
|
|
<RegistryValue Type="string" Value="[VersionFolder]pwsh.exe -NoExit -RemoveWorkingDirectoryTrailingCharacter -WorkingDirectory "%1" -Command "$host.UI.RawUI.WindowTitle = '$(var.ProductName) $(var.SimpleProductVersion) ($(sys.BUILDARCH))'""/>
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have reviewed the code changes and agree with yotsuda's analysis. The PR correctly identifies that %1 should be used for the selected item path instead of %V!, but removing the trailing sentinel character ! while keeping -RemoveWorkingDirectoryTrailingCharacter will cause the issues yotsuda described. The suggested fix to use %1! maintains both the correct path variable and the workaround for the escaping issue from #8287.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
|
</RegistryKey>
|
|
|
<RegistryKey Root="HKCR" Key="Directory\ContextMenus\$(var.ProductName)$(var.SimpleProductVersion)$(sys.BUILDARCH)\shell\runas\command">
|
|
|
<RegistryValue Type="string" Value="[VersionFolder]pwsh.exe -NoExit -RemoveWorkingDirectoryTrailingCharacter -WorkingDirectory "%V!" -Command "$host.UI.RawUI.WindowTitle = '$(var.ProductName) $(var.SimpleProductVersion) ($(sys.BUILDARCH))'""/>
|
|
|
<RegistryValue Type="string" Value="[VersionFolder]pwsh.exe -NoExit -RemoveWorkingDirectoryTrailingCharacter -WorkingDirectory "%1" -Command "$host.UI.RawUI.WindowTitle = '$(var.ProductName) $(var.SimpleProductVersion) ($(sys.BUILDARCH))'""/>
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. The same issue applies here for the elevated (runas) context menu entry. Using %1! instead of %1 ensures proper path handling.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
I was the reviewer who pointed out that the ! sentinel character must be preserved (i.e., %1! not bare %1). That part was correct -- without !, -RemoveWorkingDirectoryTrailingCharacter cannot function. However, my review did not question whether changing %V to %1 itself was valid. After this PR was closed, I investigated that aspect and found that changing %V to %1 would break the context menu in several scenarios. I want to share these findings to prevent future contributors from going down the same path.
Background
The same Directory\ContextMenus\...\command entries (lines 457-466 in Product.wxs) are invoked from five different parent contexts via ExtendedSubCommandsKey:
| Parent key |
Trigger |
Directory\Background\shell |
Right-click the background of an open folder |
Drive\shell |
Right-click a drive |
DesktopBackground\shell |
Right-click the desktop background |
Directory\shell |
Right-click a folder |
LibraryFolder\background\shell |
Right-click the background in a Library folder |
Testing
I created temporary registry entries under HKCU on Windows 11 (Build 26200) to test what %V! and %1! actually resolve to in each context. I tested with both pwsh.exe and cmd.exe to rule out PowerShell-specific behavior.
Right-clicking a folder (Directory\shell)
Both %V! and %1! resolve to the same value -- the path of the right-clicked folder with ! appended. There is no behavioral difference.
%V! -> C:\Users\username\Downloads\SomeFolder!
%1! -> C:\Users\username\Downloads\SomeFolder!
Right-clicking the background of an open folder (Directory\Background\shell)
%V! resolves to the current folder path with ! appended (correct).
%1! -- the command does not execute at all. Across three separate tests (pwsh script logging, cmd.exe echo, cmd.exe echo with bracket-delimited output), %1 in a background context produced zero output. Explorer does not launch the process.
%V! -> C:\Users! (correct)
%1! -> (command not executed)
Conclusion
%V to %1 would break "Open here" for three of the five contexts: Directory\Background\shell (the most common way to use this menu), DesktopBackground\shell, and likely LibraryFolder\background\shell. The command simply does not execute.
- For
Directory\shell (right-clicking a folder), %V and %1 resolve to the identical value, so the change provides no benefit.
- The original issue (wrong folder opening on VM shared drives with "Open here as Administrator") is likely unrelated to
%V vs %1. A more probable cause is that user-session drive mappings are not available in the elevated process, which is a known Windows limitation.
The current code using %V! is correct. No change to %1 should be made.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Reviewers
2 more reviewers
Reviewers whose approvals may not affect merge requirements
Uh oh!
There was an error while loading. Please reload this page.
Assignees
No one assigned
Labels
Waiting on Author
The PR was reviewed and requires changes or comments from the author before being accept
Milestone
No milestone
Development
Successfully merging this pull request may close these issues.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
|