From 576e2a7d2c6778364969ed712a79c67f8f3fbcce Mon Sep 17 00:00:00 2001 From: Laszlo Nemeth <57342539+donlaci@users.noreply.github.com> Date: Thu, 28 Mar 2024 15:33:12 +0100 Subject: [PATCH] [CmdNotFound]Support PowerShell Preview installation (#32034) * [CommandNotFound] extending to detect PowerShellPreview installations * Re-implementing directory search, where the PowerShell Preview is installed * Re-implementing preview or normal powershell executable usage --- .../ViewModels/CmdNotFoundViewModel.cs | 53 +++++++++++++++++-- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/src/settings-ui/Settings.UI/ViewModels/CmdNotFoundViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/CmdNotFoundViewModel.cs index 85b5c3bf2e..a861e1e7ad 100644 --- a/src/settings-ui/Settings.UI/ViewModels/CmdNotFoundViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/CmdNotFoundViewModel.cs @@ -3,8 +3,10 @@ // See the LICENSE file in the project root for more information. using System; +using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using global::PowerToys.GPOWrapper; @@ -76,6 +78,9 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels private bool _isPowerShell7Detected; + private bool isPowerShellPreviewDetected; + private string powerShellPreviewPath; + public bool IsPowerShell7Detected { get => _isPowerShell7Detected; @@ -129,6 +134,18 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels get => RuntimeInformation.OSArchitecture == System.Runtime.InteropServices.Architecture.Arm64; } + public string RunPowerShellOrPreviewScript(string powershellExecutable, string powershellArguments, bool hidePowerShellWindow = false) + { + if (isPowerShellPreviewDetected) + { + return RunPowerShellScript(Path.Combine(powerShellPreviewPath, "pwsh-preview.cmd"), powershellArguments, hidePowerShellWindow); + } + else + { + return RunPowerShellScript(powershellExecutable, powershellArguments, hidePowerShellWindow); + } + } + public string RunPowerShellScript(string powershellExecutable, string powershellArguments, bool hidePowerShellWindow = false) { string outputLog = string.Empty; @@ -160,6 +177,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels public void CheckCommandNotFoundRequirements() { + isPowerShellPreviewDetected = false; var ps1File = AssemblyDirectory + "\\Assets\\Settings\\Scripts\\CheckCmdNotFoundRequirements.ps1"; var arguments = $"-NoProfile -NonInteractive -ExecutionPolicy Unrestricted -File \"{ps1File}\""; var result = RunPowerShellScript("pwsh.exe", arguments, true); @@ -179,6 +197,33 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels IsPowerShell7Detected = false; } + if (!IsPowerShell7Detected) + { + // powerShell Preview might be installed, check it. + try + { + // we have to search for the directory where the PowerShell preview command is located. It is added to the PATH environment variable, so we have to search for it there + foreach (string pathCandidate in Environment.GetEnvironmentVariable("PATH").Split(';')) + { + if (File.Exists(Path.Combine(pathCandidate, "pwsh-preview.cmd"))) + { + result = RunPowerShellScript(Path.Combine(pathCandidate, "pwsh-preview.cmd"), arguments, true); + if (result.Contains("PowerShell 7.4 or greater detected.")) + { + isPowerShellPreviewDetected = true; + IsPowerShell7Detected = true; + powerShellPreviewPath = pathCandidate; + break; + } + } + } + } + catch (Exception) + { + // nothing to do. No additional PowerShell installation found + } + } + if (result.Contains("WinGet Client module detected.")) { IsWinGetClientModuleDetected = true; @@ -204,7 +249,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels { var ps1File = AssemblyDirectory + "\\Assets\\Settings\\Scripts\\InstallPowerShell7.ps1"; var arguments = $"-NoProfile -ExecutionPolicy Unrestricted -File \"{ps1File}\""; - var result = RunPowerShellScript("powershell.exe", arguments); + var result = RunPowerShellOrPreviewScript("powershell.exe", arguments); if (result.Contains("Powershell 7 successfully installed.")) { IsPowerShell7Detected = true; @@ -220,7 +265,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels { var ps1File = AssemblyDirectory + "\\Assets\\Settings\\Scripts\\InstallWinGetClientModule.ps1"; var arguments = $"-NoProfile -ExecutionPolicy Unrestricted -File \"{ps1File}\""; - var result = RunPowerShellScript("pwsh.exe", arguments); + var result = RunPowerShellOrPreviewScript("pwsh.exe", arguments); if (result.Contains("WinGet Client module detected.")) { IsWinGetClientModuleDetected = true; @@ -237,7 +282,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels { var ps1File = AssemblyDirectory + "\\Assets\\Settings\\Scripts\\EnableModule.ps1"; var arguments = $"-NoProfile -ExecutionPolicy Unrestricted -File \"{ps1File}\" -scriptPath \"{AssemblyDirectory}\\..\""; - var result = RunPowerShellScript("pwsh.exe", arguments); + var result = RunPowerShellOrPreviewScript("pwsh.exe", arguments); if (result.Contains("Module is already registered in the profile file.") || result.Contains("Module was successfully registered in the profile file.")) { @@ -252,7 +297,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels { var ps1File = AssemblyDirectory + "\\Assets\\Settings\\Scripts\\DisableModule.ps1"; var arguments = $"-NoProfile -ExecutionPolicy Unrestricted -File \"{ps1File}\""; - var result = RunPowerShellScript("pwsh.exe", arguments); + var result = RunPowerShellOrPreviewScript("pwsh.exe", arguments); if (result.Contains("Removed the Command Not Found reference from the profile file.") || result.Contains("No instance of Command Not Found was found in the profile file.")) {