Skip to content

Fix: Use %1 instead of %V! for folder context menu paths#26718

Open
tekintian wants to merge 1 commit intoPowerShell:masterfrom
tekintian:fix-context-menu-path
Open

Fix: Use %1 instead of %V! for folder context menu paths#26718
tekintian wants to merge 1 commit intoPowerShell:masterfrom
tekintian:fix-context-menu-path

Conversation

@tekintian
Copy link

  • 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:

  1. Show an error: Set-Location: Cannot find drive. A drive with the name 'Z' does not exist.
  2. 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:

  1. Line 458: openpwsh\command - Normal PowerShell launch
  2. 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.

- 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
@tekintian tekintian requested a review from a team as a code owner January 22, 2026 08:16
@microsoft-github-policy-service microsoft-github-policy-service bot added the Review - Needed The PR is being reviewed label Jan 29, 2026
@microsoft-github-policy-service
Copy link
Contributor

This pull request has been automatically marked as Review Needed because it has been there has not been any activity for 7 days.
Maintainer, please provide feedback and/or mark it as Waiting on Author

Copy link
Contributor

@yotsuda yotsuda left a 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:\UsersC:\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:

  1. Non-root paths: the last real character is stripped (C:\UsersC:\User)
  2. 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.

</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 &quot;%V!&quot; -Command &quot;$host.UI.RawUI.WindowTitle = '$(var.ProductName) $(var.SimpleProductVersion) ($(sys.BUILDARCH))'&quot;"/>
<RegistryValue Type="string" Value="[VersionFolder]pwsh.exe -NoExit -RemoveWorkingDirectoryTrailingCharacter -WorkingDirectory &quot;%1&quot; -Command &quot;$host.UI.RawUI.WindowTitle = '$(var.ProductName) $(var.SimpleProductVersion) ($(sys.BUILDARCH))'&quot;"/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<RegistryValue Type="string" Value="[VersionFolder]pwsh.exe -NoExit -RemoveWorkingDirectoryTrailingCharacter -WorkingDirectory &quot;%1&quot; -Command &quot;$host.UI.RawUI.WindowTitle = '$(var.ProductName) $(var.SimpleProductVersion) ($(sys.BUILDARCH))'&quot;"/>
<RegistryValue Type="string" Value="[VersionFolder]pwsh.exe -NoExit -RemoveWorkingDirectoryTrailingCharacter -WorkingDirectory &quot;%1!&quot; -Command &quot;$host.UI.RawUI.WindowTitle = '$(var.ProductName) $(var.SimpleProductVersion) ($(sys.BUILDARCH))'&quot;"/>

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.

</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 &quot;%V!&quot; -Command &quot;$host.UI.RawUI.WindowTitle = '$(var.ProductName) $(var.SimpleProductVersion) ($(sys.BUILDARCH))'&quot;"/>
<RegistryValue Type="string" Value="[VersionFolder]pwsh.exe -NoExit -RemoveWorkingDirectoryTrailingCharacter -WorkingDirectory &quot;%1&quot; -Command &quot;$host.UI.RawUI.WindowTitle = '$(var.ProductName) $(var.SimpleProductVersion) ($(sys.BUILDARCH))'&quot;"/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<RegistryValue Type="string" Value="[VersionFolder]pwsh.exe -NoExit -RemoveWorkingDirectoryTrailingCharacter -WorkingDirectory &quot;%1&quot; -Command &quot;$host.UI.RawUI.WindowTitle = '$(var.ProductName) $(var.SimpleProductVersion) ($(sys.BUILDARCH))'&quot;"/>
<RegistryValue Type="string" Value="[VersionFolder]pwsh.exe -NoExit -RemoveWorkingDirectoryTrailingCharacter -WorkingDirectory &quot;%1!&quot; -Command &quot;$host.UI.RawUI.WindowTitle = '$(var.ProductName) $(var.SimpleProductVersion) ($(sys.BUILDARCH))'&quot;"/>

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.

Copy link

@aaron-seq aaron-seq left a 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.

</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 &quot;%V!&quot; -Command &quot;$host.UI.RawUI.WindowTitle = '$(var.ProductName) $(var.SimpleProductVersion) ($(sys.BUILDARCH))'&quot;"/>
<RegistryValue Type="string" Value="[VersionFolder]pwsh.exe -NoExit -RemoveWorkingDirectoryTrailingCharacter -WorkingDirectory &quot;%1&quot; -Command &quot;$host.UI.RawUI.WindowTitle = '$(var.ProductName) $(var.SimpleProductVersion) ($(sys.BUILDARCH))'&quot;"/>

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.

</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 &quot;%V!&quot; -Command &quot;$host.UI.RawUI.WindowTitle = '$(var.ProductName) $(var.SimpleProductVersion) ($(sys.BUILDARCH))'&quot;"/>
<RegistryValue Type="string" Value="[VersionFolder]pwsh.exe -NoExit -RemoveWorkingDirectoryTrailingCharacter -WorkingDirectory &quot;%1&quot; -Command &quot;$host.UI.RawUI.WindowTitle = '$(var.ProductName) $(var.SimpleProductVersion) ($(sys.BUILDARCH))'&quot;"/>

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.

@microsoft-github-policy-service microsoft-github-policy-service bot added Waiting on Author The PR was reviewed and requires changes or comments from the author before being accept and removed Review - Needed The PR is being reviewed labels Feb 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Waiting on Author The PR was reviewed and requires changes or comments from the author before being accept

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants