@@ -32,7 +32,6 @@ public class PowerShellHostViewModel : ViewModelBase, IProfileManager
3232 #region Variables
3333 private static readonly ILog Log = LogManager . GetLogger ( typeof ( PowerShellHostViewModel ) ) ;
3434
35- private readonly IDialogCoordinator _dialogCoordinator ;
3635 private readonly DispatcherTimer _searchDispatcherTimer = new ( ) ;
3736
3837 public IInterTabClient InterTabClient { get ; }
@@ -307,16 +306,15 @@ public bool ProfileContextMenuIsOpen
307306
308307 #region Constructor, load settings
309308
310- public PowerShellHostViewModel ( IDialogCoordinator instance )
309+ public PowerShellHostViewModel ( )
311310 {
312311 _isLoading = true ;
313312
314- _dialogCoordinator = instance ;
315-
316313 // Check if PowerShell executable is configured
317314 CheckExecutable ( ) ;
318315
319316 // Try to find PowerShell executable
317+
320318 if ( ! IsExecutableConfigured )
321319 TryFindExecutable ( ) ;
322320
@@ -569,8 +567,20 @@ private void TryFindExecutable()
569567
570568 var applicationFilePath = ApplicationHelper . Find ( PowerShell . PwshFileName ) ;
571569
572- if ( string . IsNullOrEmpty ( applicationFilePath ) )
570+ // Workaround for: https://github.com/BornToBeRoot/NETworkManager/issues/3223
571+ if ( applicationFilePath . EndsWith ( "AppData\\ Local\\ Microsoft\\ WindowsApps\\ pwsh.exe" ) )
572+ {
573+ Log . Info ( "Found pwsh.exe in AppData (Microsoft Store installation). Trying to resolve real path..." ) ;
574+
575+ var realPwshPath = FindRealPwshPath ( applicationFilePath ) ;
576+
577+ if ( realPwshPath != null )
578+ applicationFilePath = realPwshPath ;
579+ }
580+ else if ( string . IsNullOrEmpty ( applicationFilePath ) )
581+ {
573582 applicationFilePath = ApplicationHelper . Find ( PowerShell . WindowsPowerShellFileName ) ;
583+ }
574584
575585 SettingsManager . Current . PowerShell_ApplicationFilePath = applicationFilePath ;
576586
@@ -580,6 +590,61 @@ private void TryFindExecutable()
580590 Log . Warn ( "Install PowerShell or configure the path in the settings." ) ;
581591 }
582592
593+ /// <summary>
594+ /// Resolves the actual installation path of a PowerShell executable that was installed via the
595+ /// Microsoft Store / WindowsApps and therefore appears as a proxy stub in the user's AppData.
596+ ///
597+ /// Typical input is a path like:
598+ /// <c>C:\Users\{USERNAME}\AppData\Local\Microsoft\WindowsApps\pwsh.exe</c>
599+ ///
600+ /// This helper attempts to locate the corresponding real executable under the Program Files
601+ /// WindowsApps package layout, e.g.:
602+ /// <c>C:\Program Files\WindowsApps\Microsoft.PowerShell_7.*_8wekyb3d8bbwe\pwsh.exe</c>.
603+ ///
604+ /// Workaround for: https://github.com/BornToBeRoot/NETworkManager/issues/3223
605+ /// </summary>
606+ /// <param name="path">Path to the pwsh proxy stub, typically located under the current user's <c>%LocalAppData%\Microsoft\WindowsApps\pwsh.exe</c>.</param>
607+ /// <returns>Full path to the real pwsh executable under Program Files WindowsApps when found; otherwise null.</returns>
608+ private string FindRealPwshPath ( string path )
609+ {
610+ try
611+ {
612+ var command = "(Get-Command pwsh).Source" ;
613+
614+ ProcessStartInfo psi = new ( )
615+ {
616+ FileName = path ,
617+ Arguments = $ "-NoProfile -ExecutionPolicy Bypass -Command \" { command } \" ",
618+ RedirectStandardOutput = true ,
619+ UseShellExecute = false ,
620+ CreateNoWindow = true
621+ } ;
622+
623+ using Process process = Process . Start ( psi ) ;
624+
625+ string output = process . StandardOutput . ReadToEnd ( ) ;
626+
627+ process . WaitForExit ( ) ;
628+
629+ if ( string . IsNullOrEmpty ( output ) )
630+ return null ;
631+
632+ output = output . Replace ( @"\\" , @"\" )
633+ . Replace ( @"\r" , string . Empty )
634+ . Replace ( @"\n" , string . Empty )
635+ . Replace ( "\r \n " , string . Empty )
636+ . Replace ( "\n " , string . Empty )
637+ . Replace ( "\r " , string . Empty )
638+ . Trim ( ) ;
639+
640+ return output ;
641+ }
642+ catch
643+ {
644+ return null ;
645+ }
646+ }
647+
583648 private Task Connect ( string host = null )
584649 {
585650 var childWindow = new PowerShellConnectChildWindow ( ) ;
0 commit comments