diff --git a/src/gsudo.Wrappers/gsudoModule.psm1 b/src/gsudo.Wrappers/gsudoModule.psm1
index e12a79e..6ec205c 100644
--- a/src/gsudo.Wrappers/gsudoModule.psm1
+++ b/src/gsudo.Wrappers/gsudoModule.psm1
@@ -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');
diff --git a/src/gsudo/AppSettings/PathPrecedenceSetting.cs b/src/gsudo/AppSettings/PathPrecedenceSetting.cs
new file mode 100644
index 0000000..d17b4f5
--- /dev/null
+++ b/src/gsudo/AppSettings/PathPrecedenceSetting.cs
@@ -0,0 +1,55 @@
+using gsudo.Helpers;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+
+namespace gsudo.AppSettings
+{
+ ///
+ /// 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.
+ ///
+ internal class PathPrecedenceSetting : RegistrySetting
+ {
+ 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 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);
+ }
+ }
+}
diff --git a/src/gsudo/AppSettings/Settings.cs b/src/gsudo/AppSettings/Settings.cs
index 0c622af..b4f66c9 100644
--- a/src/gsudo/AppSettings/Settings.cs
+++ b/src/gsudo/AppSettings/Settings.cs
@@ -98,6 +98,8 @@ namespace gsudo
deserializer: ExtensionMethods.ParseEnum,
scope: RegistrySettingScope.Any);
+ public static RegistrySetting PathOverrideSetting = new PathPrecedenceSetting();
+
public static IDictionary AllKeys =>
new Dictionary(StringComparer.OrdinalIgnoreCase)
.Add(
@@ -120,7 +122,8 @@ namespace gsudo
PowerShellLoadProfile,
SecurityEnforceUacIsolation,
- ExceptionList
+ ExceptionList,
+ PathOverrideSetting
);
internal static TimeSpan TimeSpanParseWithInfinite(string value)