diff --git a/src/chocolatey/infrastructure.app/ApplicationParameters.cs b/src/chocolatey/infrastructure.app/ApplicationParameters.cs
index dad8b6d887..f2e7a170a0 100644
--- a/src/chocolatey/infrastructure.app/ApplicationParameters.cs
+++ b/src/chocolatey/infrastructure.app/ApplicationParameters.cs
@@ -75,6 +75,9 @@ public static class Environment
{
public static readonly string Path = "Path";
public static readonly string PathExtensions = "PATHEXT";
+ public static readonly string PsModulePath = "PSModulePath";
+ public static readonly string Username = "USERNAME";
+ public static readonly string ProcessorArchitecture = "PROCESSOR_ARCHITECTURE";
public static readonly string EnvironmentSeparator = ";";
}
diff --git a/src/chocolatey/infrastructure.app/configuration/EnvironmentSettings.cs b/src/chocolatey/infrastructure.app/configuration/EnvironmentSettings.cs
index 9106e9995c..41c17d4ade 100644
--- a/src/chocolatey/infrastructure.app/configuration/EnvironmentSettings.cs
+++ b/src/chocolatey/infrastructure.app/configuration/EnvironmentSettings.cs
@@ -136,5 +136,97 @@ private static void set_licensed_environment(ChocolateyConfiguration config)
}
}
}
+
+ ///
+ /// Refreshes the current environment values with the updated values,
+ /// even if updated outside of the current process.
+ ///
+ ///
+ /// This does not remove environment variables, but will ensure all updates are shown.
+ /// To see actual update with removed variables, one will need to restart a shell.
+ ///
+ public static void update_environment_variables()
+ {
+ // grab original values
+ var originalEnvironmentVariables = convert_to_case_insensitive_dictionary(Environment.GetEnvironmentVariables(EnvironmentVariableTarget.Process));
+ var userName = originalEnvironmentVariables[ApplicationParameters.Environment.Username].to_string();
+ var architecture = originalEnvironmentVariables[ApplicationParameters.Environment.ProcessorArchitecture].to_string();
+ var originalPath = originalEnvironmentVariables[ApplicationParameters.Environment.Path]
+ .to_string()
+ .Split(new[] { ApplicationParameters.Environment.EnvironmentSeparator }, StringSplitOptions.RemoveEmptyEntries);
+ var originalPathExt = originalEnvironmentVariables[ApplicationParameters.Environment.PathExtensions]
+ .to_string()
+ .Split(new[] { ApplicationParameters.Environment.EnvironmentSeparator }, StringSplitOptions.RemoveEmptyEntries);
+ var originalPsModulePath = originalEnvironmentVariables[ApplicationParameters.Environment.PsModulePath]
+ .to_string()
+ .Split(new[] { ApplicationParameters.Environment.EnvironmentSeparator }, StringSplitOptions.RemoveEmptyEntries);
+
+ // get updated values from the registry
+ var machineVariables = convert_to_case_insensitive_dictionary(Environment.GetEnvironmentVariables(EnvironmentVariableTarget.Machine));
+ var userVariables = convert_to_case_insensitive_dictionary(Environment.GetEnvironmentVariables(EnvironmentVariableTarget.User));
+
+ // refresh current values with updated values, mathine first
+ refresh_environment_variables(machineVariables);
+ refresh_environment_variables(userVariables);
+
+ // restore process overridden variables
+ if (originalEnvironmentVariables.Contains(ApplicationParameters.Environment.Username)) Environment.SetEnvironmentVariable(ApplicationParameters.Environment.Username, userName);
+ if (originalEnvironmentVariables.Contains(ApplicationParameters.Environment.ProcessorArchitecture)) Environment.SetEnvironmentVariable(ApplicationParameters.Environment.ProcessorArchitecture, architecture);
+
+ // combine environment values that append together
+ var updatedPath = "{0};{1};".format_with(
+ machineVariables[ApplicationParameters.Environment.Path].to_string(),
+ userVariables[ApplicationParameters.Environment.Path].to_string()
+ ).Replace(";;", ";");
+ var updatedPathExt = "{0};{1};".format_with(
+ machineVariables[ApplicationParameters.Environment.PathExtensions].to_string(),
+ userVariables[ApplicationParameters.Environment.PathExtensions].to_string()
+ ).Replace(";;", ";");
+ var updatedPsModulePath = "{0};{1};".format_with(
+ userVariables[ApplicationParameters.Environment.PsModulePath].to_string(),
+ machineVariables[ApplicationParameters.Environment.PsModulePath].to_string()
+ ).Replace(";;", ";");
+
+ // add back in process items
+ updatedPath += append_process_items(updatedPath, originalPath);
+ updatedPathExt += append_process_items(updatedPathExt, originalPathExt);
+ updatedPsModulePath += append_process_items(updatedPsModulePath, originalPsModulePath);
+
+ Environment.SetEnvironmentVariable(ApplicationParameters.Environment.Path, updatedPath);
+ Environment.SetEnvironmentVariable(ApplicationParameters.Environment.PathExtensions, updatedPathExt);
+ Environment.SetEnvironmentVariable(ApplicationParameters.Environment.PsModulePath, updatedPsModulePath);
+ }
+
+ private static IDictionary convert_to_case_insensitive_dictionary(IDictionary originalDictionary)
+ {
+ return new Hashtable(originalDictionary, StringComparer.InvariantCultureIgnoreCase);
+ }
+
+ private static void refresh_environment_variables(IDictionary environmentVariables)
+ {
+ foreach (DictionaryEntry variable in environmentVariables)
+ {
+ Environment.SetEnvironmentVariable(variable.Key.to_string(), variable.Value.to_string());
+ }
+ }
+
+ private static string append_process_items(string currentValues, IEnumerable originalValues)
+ {
+ var additionalItems = new StringBuilder();
+ var items = currentValues.Split(
+ new[] { ApplicationParameters.Environment.EnvironmentSeparator },
+ StringSplitOptions.RemoveEmptyEntries
+ );
+
+ foreach (string originalValue in originalValues.or_empty_list_if_null())
+ {
+ if (!items.Contains(originalValue, StringComparer.InvariantCultureIgnoreCase))
+ {
+ additionalItems.AppendFormat("{0};", originalValue);
+ }
+ }
+
+ return additionalItems.to_string();
+ }
}
}