Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
EnvironmentProvider.cs248 linesDownload Raw Back to namespaces
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System;5using System.Collections;6using System.Collections.Generic;7using System.Collections.ObjectModel;8using System.Management.Automation;9using System.Management.Automation.Provider;10 11using Dbg = System.Management.Automation;12 13namespace Microsoft.PowerShell.Commands14{15    /// <summary>16    /// This provider is the data accessor for environment variables. It uses17    /// the SessionStateProviderBase as the base class to produce a view on18    /// session state data.19    /// </summary>20    [CmdletProvider(EnvironmentProvider.ProviderName, ProviderCapabilities.ShouldProcess)]21    public sealed class EnvironmentProvider : SessionStateProviderBase22    {23        /// <summary>24        /// Gets the name of the provider.25        /// </summary>26        public const string ProviderName = "Environment";27 28        #region Constructor29 30        /// <summary>31        /// The constructor for the provider that exposes environment variables to the user32        /// as drives.33        /// </summary>34        public EnvironmentProvider()35        {36        }37 38        #endregion Constructor39 40        #region DriveCmdletProvider overrides41 42        /// <summary>43        /// Initializes the alias drive.44        /// </summary>45        /// <returns>46        /// An array of a single PSDriveInfo object representing the alias drive.47        /// </returns>48        protected override Collection<PSDriveInfo> InitializeDefaultDrives()49        {50            string description = SessionStateStrings.EnvironmentDriveDescription;51 52            PSDriveInfo envDrive =53                new PSDriveInfo(54                    DriveNames.EnvironmentDrive,55                    ProviderInfo,56                    string.Empty,57                    description,58                    null);59 60            Collection<PSDriveInfo> drives = new Collection<PSDriveInfo>();61            drives.Add(envDrive);62            return drives;63        }64 65        #endregion DriveCmdletProvider overrides66 67        #region protected members68 69        /// <summary>70        /// Gets a environment variable from session state.71        /// </summary>72        /// <param name="name">73        /// The name of the environment variable to retrieve.74        /// </param>75        /// <returns>76        /// A DictionaryEntry that represents the value of the environment variable.77        /// </returns>78        internal override object GetSessionStateItem(string name)79        {80            Dbg.Diagnostics.Assert(81                !string.IsNullOrEmpty(name),82                "The caller should verify this parameter");83 84            object result = null;85 86            string value = Environment.GetEnvironmentVariable(name);87 88            if (value != null)89            {90                result = new DictionaryEntry(name, value);91            }92 93            return result;94        }95 96        /// <summary>97        /// Sets the environment variable of the specified name to the specified value.98        /// </summary>99        /// <param name="name">100        /// The name of the environment variable to set.101        /// </param>102        /// <param name="value">103        /// The new value for the environment variable.104        /// </param>105        /// <param name="writeItem">106        /// If true, the item that was set should be written to WriteItemObject.107        /// </param>108        internal override void SetSessionStateItem(string name, object value, bool writeItem)109        {110            Dbg.Diagnostics.Assert(111                !string.IsNullOrEmpty(name),112                "The caller should verify this parameter");113 114            if (value == null)115            {116                Environment.SetEnvironmentVariable(name, null);117            }118            else119            {120                // First see if we got a DictionaryEntry which represents121                // an item for this provider. If so, use the value from122                // the dictionary entry.123 124                if (value is DictionaryEntry)125                {126                    value = ((DictionaryEntry)value).Value;127                }128 129                string stringValue = value as string;130                if (stringValue == null)131                {132                    // try using ETS to convert to a string.133 134                    PSObject wrappedObject = PSObject.AsPSObject(value);135                    stringValue = wrappedObject.ToString();136                }137 138                Environment.SetEnvironmentVariable(name, stringValue);139 140                DictionaryEntry item = new DictionaryEntry(name, stringValue);141 142                if (writeItem)143                {144                    WriteItemObject(item, name, false);145                }146            }147        }148 149        /// <summary>150        /// Removes the specified environment variable from session state.151        /// </summary>152        /// <param name="name">153        /// The name of the environment variable to remove from session state.154        /// </param>155        internal override void RemoveSessionStateItem(string name)156        {157            Dbg.Diagnostics.Assert(158                !string.IsNullOrEmpty(name),159                "The caller should verify this parameter");160 161            Environment.SetEnvironmentVariable(name, null);162        }163 164        /// <summary>165        /// Gets a flattened view of the environment variables in session state.166        /// </summary>167        /// <returns>168        /// An IDictionary representing the flattened view of the environment variables in169        /// session state.170        /// </returns>171        internal override IDictionary GetSessionStateTable()172        {173            // Environment variables are case-sensitive on Unix and174            // case-insensitive on Windows175#if UNIX176            Dictionary<string, DictionaryEntry> providerTable =177                new Dictionary<string, DictionaryEntry>(StringComparer.Ordinal);178#else179            Dictionary<string, DictionaryEntry> providerTable =180                new Dictionary<string, DictionaryEntry>(StringComparer.OrdinalIgnoreCase);181#endif182 183            // The environment variables returns a dictionary of keys and values that are184            // both strings. We want to return a dictionary with the key as a string and185            // the value as the DictionaryEntry containing both the name and env variable186            // value.187 188            IDictionary environmentTable = Environment.GetEnvironmentVariables();189            foreach (DictionaryEntry entry in environmentTable)190            {191                if (!providerTable.TryAdd((string)entry.Key, entry))192                {   // Windows only: duplicate key (variable name that differs only in case)193                    // NOTE: Even though this shouldn't happen, it can, e.g. when npm194                    //       creates duplicate environment variables that differ only in case -195                    //       see https://github.com/PowerShell/PowerShell/issues/6305.196                    //       However, because retrieval *by name* later is invariably197                    //       case-INsensitive, in effect only a *single* variable exists.198                    //       We simply ask Environment.GetEnvironmentVariable() for the effective value199                    //       and use that as the only entry, because for a given key 'foo' (and all its case variations),200                    //       that is guaranteed to match what $env:FOO and [environment]::GetEnvironmentVariable('foo') return.201                    //       (If, by contrast, we just used `entry` as-is every time a duplicate is encountered,202                    //        it could - intermittently - represent a value *other* than the effective one.)203                    string effectiveValue = Environment.GetEnvironmentVariable((string)entry.Key);204                    if (((string)entry.Value).Equals(effectiveValue, StringComparison.Ordinal))205                    { // We've found the effective definition.206                        // Note: We *recreate* the entry so that the specific name casing of the207                        //       effective definition is also reflected. However, if the case variants208                        //       define the same value, it is unspecified which name variant is reflected209                        //       in Get-Item env: output; given the always case-insensitive nature of the retrieval,210                        //       that shouldn't matter.211                        providerTable.Remove((string)entry.Key);212                        providerTable.Add((string)entry.Key, entry);213                    }214                }215            }216 217            return providerTable;218        }219 220        /// <summary>221        /// Gets the Value property of the DictionaryEntry item.222        /// </summary>223        /// <param name="item">224        /// The item to get the value from.225        /// </param>226        /// <returns>227        /// The value of the item.228        /// </returns>229        internal override object GetValueOfItem(object item)230        {231            Dbg.Diagnostics.Assert(232                item != null,233                "Caller should verify the item parameter");234 235            object value = item;236 237            if (item is DictionaryEntry)238            {239                value = ((DictionaryEntry)item).Value;240            }241 242            return value;243        }244 245        #endregion protected members246    }247}248