Merge pull request #353 from gerardog/feature/path-precedence

New PathPrecedence Setting to reorder the PATH environment variable
This commit is contained in:
Gerardo Grignoli 2024-05-26 15:36:43 -03:00 committed by GitHub
commit ccf99bf7f9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 60 additions and 2 deletions

View File

@ -134,7 +134,7 @@ if ($gsudoAutoComplete) {
'--integrity' = $integrityOptions;
'-i' = $integrityOptions;
'cache' = @('on', 'off', 'help');
'config' = @('CacheMode', 'CacheDuration', 'LogLevel', 'NewWindow.Force', 'NewWindow.CloseBehaviour', 'Prompt', 'PipedPrompt', 'ForceAttachedConsole', 'ForcePipedConsole', 'ForceVTConsole', 'CopyEnvironmentVariables', 'CopyNetworkShares', 'PowerShellLoadProfile', 'SecurityEnforceUacIsolation', 'ExceptionList');
'config' = @('CacheMode', 'CacheDuration', 'LogLevel', 'NewWindow.Force', 'NewWindow.CloseBehaviour', 'Prompt', 'PipedPrompt', 'PathPrecedence', 'ForceAttachedConsole', 'ForcePipedConsole', 'ForceVTConsole', 'CopyEnvironmentVariables', 'CopyNetworkShares', 'PowerShellLoadProfile', 'SecurityEnforceUacIsolation', 'ExceptionList');
'cachemode' = @('Auto', 'Disabled', 'Explicit', '--reset');
'loglevel' = @('All', 'Debug', 'Info', 'Warning', 'Error', 'None', '--reset');
'NewWindow.CloseBehaviour' = @('KeepShellOpen', 'PressKeyToClose', 'OsDefault', '--reset');

View File

@ -0,0 +1,55 @@
using gsudo.Helpers;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace gsudo.AppSettings
{
/// <summary>
/// Reorders the PATH environment variable to prioritize gsudo's path.
/// Saving the boolean value to the registry is anecdotical, the real change is done in the environment variable.
/// </summary>
internal class PathPrecedenceSetting : RegistrySetting<bool>
{
public PathPrecedenceSetting():
base("PathPrecedence", false, bool.Parse, RegistrySettingScope.GlobalOnly)
{
}
public override void Save(string newValue, bool global)
{
bool bNewValue = bool.Parse(newValue);
var ourPath = Path.GetDirectoryName(ProcessFactory.FindExecutableInPath("gsudo.exe")) // shim
?? Path.GetDirectoryName(ProcessHelper.GetOwnExeName());
var system32Path = Environment.GetFolderPath(Environment.SpecialFolder.System);
var allPaths = Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.Machine).Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
// I could also do .Distinct(StringComparer.OrdinalIgnoreCase);
// ...and it works well on local, but may be out of our responsibility to fix that.
IEnumerable<string> newPath;
if (bNewValue)
newPath = new[] { ourPath }.Concat(allPaths.Where(p => !p.Equals(ourPath, StringComparison.OrdinalIgnoreCase)));
else
newPath = allPaths.Where(p => !p.Equals(ourPath, StringComparison.OrdinalIgnoreCase)).Concat(new[] { ourPath });
var finalStringPath = string.Join(";", newPath);
Logger.Instance.Log($"Updating PATH environment variable to: {finalStringPath}", LogLevel.Debug);
Environment.SetEnvironmentVariable("Path", finalStringPath, EnvironmentVariableTarget.Machine);
base.Save(newValue, global);
if (bNewValue)
Logger.Instance.Log($"\"{ourPath}\" path is now prioritized in the PATH environment variable.", LogLevel.Info);
else
Logger.Instance.Log($"\"{system32Path}\" path is now prioritized in the PATH environment variable.", LogLevel.Info);
Logger.Instance.Log("Please restart all your consoles to ensure the change makes effect.", LogLevel.Warning);
}
}
}

View File

@ -98,6 +98,8 @@ namespace gsudo
deserializer: ExtensionMethods.ParseEnum<CloseBehaviour>,
scope: RegistrySettingScope.Any);
public static RegistrySetting<bool> PathOverrideSetting = new PathPrecedenceSetting();
public static IDictionary<string, RegistrySetting> AllKeys =>
new Dictionary<string, RegistrySetting>(StringComparer.OrdinalIgnoreCase)
.Add(
@ -120,7 +122,8 @@ namespace gsudo
PowerShellLoadProfile,
SecurityEnforceUacIsolation,
ExceptionList
ExceptionList,
PathOverrideSetting
);
internal static TimeSpan TimeSpanParseWithInfinite(string value)