diff --git a/Source/NETworkManager/ViewModels/PowerShellHostViewModel.cs b/Source/NETworkManager/ViewModels/PowerShellHostViewModel.cs
index a81f96da32..e35ec44932 100644
--- a/Source/NETworkManager/ViewModels/PowerShellHostViewModel.cs
+++ b/Source/NETworkManager/ViewModels/PowerShellHostViewModel.cs
@@ -32,7 +32,6 @@ public class PowerShellHostViewModel : ViewModelBase, IProfileManager
#region Variables
private static readonly ILog Log = LogManager.GetLogger(typeof(PowerShellHostViewModel));
- private readonly IDialogCoordinator _dialogCoordinator;
private readonly DispatcherTimer _searchDispatcherTimer = new();
public IInterTabClient InterTabClient { get; }
@@ -307,16 +306,15 @@ public bool ProfileContextMenuIsOpen
#region Constructor, load settings
- public PowerShellHostViewModel(IDialogCoordinator instance)
+ public PowerShellHostViewModel()
{
_isLoading = true;
- _dialogCoordinator = instance;
-
// Check if PowerShell executable is configured
CheckExecutable();
// Try to find PowerShell executable
+
if (!IsExecutableConfigured)
TryFindExecutable();
@@ -569,8 +567,24 @@ private void TryFindExecutable()
var applicationFilePath = ApplicationHelper.Find(PowerShell.PwshFileName);
+ // Workaround for: https://github.com/BornToBeRoot/NETworkManager/issues/3223
+ if (applicationFilePath.EndsWith("AppData\\Local\\Microsoft\\WindowsApps\\pwsh.exe"))
+ {
+ Log.Info("Found pwsh.exe in AppData (Microsoft Store installation). Trying to resolve real path...");
+
+ var realPwshPath = FindRealPwshPath(applicationFilePath);
+
+ if (realPwshPath != null)
+ applicationFilePath = realPwshPath;
+ }
+
+ // Fallback to Windows PowerShell
if (string.IsNullOrEmpty(applicationFilePath))
+ {
+ Log.Warn("Failed to resolve pwsh.exe path. Falling back to Windows PowerShell.");
+
applicationFilePath = ApplicationHelper.Find(PowerShell.WindowsPowerShellFileName);
+ }
SettingsManager.Current.PowerShell_ApplicationFilePath = applicationFilePath;
@@ -580,6 +594,68 @@ private void TryFindExecutable()
Log.Warn("Install PowerShell or configure the path in the settings.");
}
+ ///
+ /// Resolves the actual installation path of a PowerShell executable that was installed via the
+ /// Microsoft Store / WindowsApps and therefore appears as a proxy stub in the user's AppData.
+ ///
+ /// Typical input is a path like:
+ /// C:\Users\{USERNAME}\AppData\Local\Microsoft\WindowsApps\pwsh.exe
+ ///
+ /// This helper attempts to locate the corresponding real executable under the Program Files
+ /// WindowsApps package layout, e.g.:
+ /// C:\Program Files\WindowsApps\Microsoft.PowerShell_7.*_8wekyb3d8bbwe\pwsh.exe.
+ ///
+ /// Workaround for: https://github.com/BornToBeRoot/NETworkManager/issues/3223
+ ///
+ /// Path to the pwsh proxy stub, typically located under the current user's %LocalAppData%\Microsoft\WindowsApps\pwsh.exe.
+ /// Full path to the real pwsh executable under Program Files WindowsApps when found; otherwise null.
+ private string FindRealPwshPath(string path)
+ {
+ try
+ {
+ var command = "(Get-Command pwsh).Source";
+
+ ProcessStartInfo psi = new()
+ {
+ FileName = path,
+ Arguments = $"-NoProfile -ExecutionPolicy Bypass -Command \"{command}\"",
+ RedirectStandardOutput = true,
+ UseShellExecute = false,
+ CreateNoWindow = true
+ };
+
+ using Process process = Process.Start(psi);
+
+ string output = process.StandardOutput.ReadToEnd();
+
+ if(!process.WaitForExit(10000))
+ {
+ process.Kill();
+ Log.Warn("Timeout while trying to resolve real pwsh path.");
+
+ return null;
+ }
+
+ if (string.IsNullOrEmpty(output))
+ return null;
+
+ output = output.Replace(@"\\", @"\")
+ .Replace(@"\r", string.Empty)
+ .Replace(@"\n", string.Empty)
+ .Replace("\r\n", string.Empty)
+ .Replace("\n", string.Empty)
+ .Replace("\r", string.Empty);
+
+ return output.Trim();
+ }
+ catch (Exception ex)
+ {
+ Log.Error($"Failed to resolve real pwsh path: {ex.Message}");
+
+ return null;
+ }
+ }
+
private Task Connect(string host = null)
{
var childWindow = new PowerShellConnectChildWindow();
diff --git a/Source/NETworkManager/Views/PowerShellHostView.xaml b/Source/NETworkManager/Views/PowerShellHostView.xaml
index 1491d03108..64358b2656 100644
--- a/Source/NETworkManager/Views/PowerShellHostView.xaml
+++ b/Source/NETworkManager/Views/PowerShellHostView.xaml
@@ -8,7 +8,6 @@
xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
xmlns:converters="clr-namespace:NETworkManager.Converters;assembly=NETworkManager.Converters"
xmlns:controls="clr-namespace:NETworkManager.Controls;assembly=NETworkManager.Controls"
- xmlns:dialogs="clr-namespace:MahApps.Metro.Controls.Dialogs;assembly=MahApps.Metro"
xmlns:viewModels="clr-namespace:NETworkManager.ViewModels"
xmlns:localization="clr-namespace:NETworkManager.Localization.Resources;assembly=NETworkManager.Localization"
xmlns:settings="clr-namespace:NETworkManager.Settings;assembly=NETworkManager.Settings"
@@ -18,7 +17,6 @@
xmlns:profiles="clr-namespace:NETworkManager.Profiles;assembly=NETworkManager.Profiles"
xmlns:wpfHelpers="clr-namespace:NETworkManager.Utilities.WPF;assembly=NETworkManager.Utilities.WPF"
xmlns:networkManager="clr-namespace:NETworkManager"
- dialogs:DialogParticipation.Register="{Binding}"
Loaded="UserControl_Loaded"
mc:Ignorable="d" d:DataContext="{d:DesignInstance viewModels:PowerShellHostViewModel}">
diff --git a/Source/NETworkManager/Views/PowerShellHostView.xaml.cs b/Source/NETworkManager/Views/PowerShellHostView.xaml.cs
index b89a38879c..1edb19d556 100644
--- a/Source/NETworkManager/Views/PowerShellHostView.xaml.cs
+++ b/Source/NETworkManager/Views/PowerShellHostView.xaml.cs
@@ -1,5 +1,4 @@
-using MahApps.Metro.Controls.Dialogs;
-using NETworkManager.ViewModels;
+using NETworkManager.ViewModels;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
@@ -9,7 +8,7 @@ namespace NETworkManager.Views;
public partial class PowerShellHostView
{
- private readonly PowerShellHostViewModel _viewModel = new(DialogCoordinator.Instance);
+ private readonly PowerShellHostViewModel _viewModel = new();
private bool _loaded;
diff --git a/Website/docs/changelog/next-release.md b/Website/docs/changelog/next-release.md
index 776bd0329d..ea7d42180d 100644
--- a/Website/docs/changelog/next-release.md
+++ b/Website/docs/changelog/next-release.md
@@ -63,7 +63,14 @@ Release date: **xx.xx.2025**
## Bug Fixes
-- The new profile filter popup introduced in version `2025.10.18.0` was instantly closed when a `PuTTY`, `PowerShell` or `AWS Session Manager` session was opened and the respective application / view was selected. [#3219](https://github.com/BornToBeRoot/NETworkManager/pull/3219)
+**PowerShell**
+
+- Resolve the actual path to `pwsh.exe` under `C:\Program Files\WindowsApps\` instead of relying on the stub located at `%LocalAppData%\Microsoft\WindowsApps\`. The stub simply redirects to the real executable, and settings such as themes are applied only to the real binary via the registry. [#3246](https://github.com/BornToBeRoot/NETworkManager/pull/3246)
+- The new profile filter popup introduced in version `2025.10.18.0` was instantly closed when a `PowerShell` session was opened and the respective application / view was selected. [#3219](https://github.com/BornToBeRoot/NETworkManager/pull/3219)
+
+**PuTTY**
+
+- The new profile filter popup introduced in version `2025.10.18.0` was instantly closed when a `PuTTY` session was opened and the respective application / view was selected. [#3219](https://github.com/BornToBeRoot/NETworkManager/pull/3219)
## Dependencies, Refactoring & Documentation