From 598cebf7b2f0b5bb0b0add97c6393ccfaaa792f5 Mon Sep 17 00:00:00 2001 From: Ilya Date: Wed, 21 Jun 2017 02:08:02 +0400 Subject: [PATCH] Add cache for GetApplicationBase (#3969) --- .../host/msh/Telemetry.cs | 2 +- .../CoreCLR/CorePsPlatform.cs | 2 +- .../common/DisplayDatabase/FormatTable.cs | 3 +- .../common/DisplayDatabase/typeDataManager.cs | 2 +- .../engine/DataStoreAdapterProvider.cs | 2 +- .../engine/InitialSessionState.cs | 6 +- .../engine/Modules/ImportModuleCommand.cs | 8 +-- .../engine/Modules/ModuleCmdletBase.cs | 58 +++++++++---------- .../engine/Modules/ModuleIntrinsics.cs | 2 +- .../engine/Modules/ModuleUtils.cs | 2 +- .../engine/TypeTable.cs | 5 +- .../engine/Utils.cs | 18 ++---- .../hostifaces/PowerShellProcessInstance.cs | 4 +- .../remoting/commands/CustomShellCommands.cs | 4 +- .../help/UpdateHelpCommand.cs | 2 +- .../minishell/api/FormatAndTypeDataHelper.cs | 2 +- .../security/Authenticode.cs | 2 +- .../singleshell/config/MshSnapinInfo.cs | 2 +- .../utils/PSTelemetryMethods.cs | 2 +- 19 files changed, 59 insertions(+), 69 deletions(-) diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/Telemetry.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/Telemetry.cs index bf70135a5b..58987b322a 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/Telemetry.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/Telemetry.cs @@ -24,7 +24,7 @@ namespace Microsoft.PowerShell // The path to the semaphore file which enables telemetry private static string TelemetrySemaphoreFilePath = Path.Combine( - Utils.GetApplicationBase(Utils.DefaultPowerShellShellID), + Utils.DefaultPowerShellAppBase, TelemetrySemaphoreFilename); // Telemetry client to be reused when we start sending more telemetry diff --git a/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs b/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs index d3ad8577e9..b208e65524 100644 --- a/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs +++ b/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs @@ -159,7 +159,7 @@ namespace System.Management.Automation if (IsNanoServer || IsIoT) { _isInbox = string.Equals( - Utils.GetApplicationBase(Utils.DefaultPowerShellShellID), + Utils.DefaultPowerShellAppBase, Utils.GetApplicationBaseFromRegistry(Utils.DefaultPowerShellShellID), StringComparison.OrdinalIgnoreCase); } diff --git a/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DisplayDatabase/FormatTable.cs b/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DisplayDatabase/FormatTable.cs index 2caaf34487..32d3a485b5 100644 --- a/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DisplayDatabase/FormatTable.cs +++ b/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DisplayDatabase/FormatTable.cs @@ -306,8 +306,7 @@ namespace System.Management.Automation.Runspaces /// public static FormatTable LoadDefaultFormatFiles() { - string shellId = Utils.DefaultPowerShellShellID; - string psHome = Utils.GetApplicationBase(shellId); + string psHome = Utils.DefaultPowerShellAppBase; List defaultFormatFiles = new List(); if (!string.IsNullOrEmpty(psHome)) { diff --git a/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DisplayDatabase/typeDataManager.cs b/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DisplayDatabase/typeDataManager.cs index 3ef1780641..bcfe4df4e0 100644 --- a/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DisplayDatabase/typeDataManager.cs +++ b/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DisplayDatabase/typeDataManager.cs @@ -490,7 +490,7 @@ namespace Microsoft.PowerShell.Commands.Internal.Format { var builtInGenerators = new Dictionary>(StringComparer.OrdinalIgnoreCase); - var psHome = Utils.GetApplicationBase(Utils.DefaultPowerShellShellID); + var psHome = Utils.DefaultPowerShellAppBase; builtInGenerators.Add(Path.Combine(psHome, "Certificate.format.ps1xml"), GetBuiltin(false, Certificate_Format_Ps1Xml.GetFormatData)); builtInGenerators.Add(Path.Combine(psHome, "Diagnostics.Format.ps1xml"), GetBuiltin(false, Diagnostics_Format_Ps1Xml.GetFormatData)); diff --git a/src/System.Management.Automation/engine/DataStoreAdapterProvider.cs b/src/System.Management.Automation/engine/DataStoreAdapterProvider.cs index 85a358fdbb..8626060c73 100644 --- a/src/System.Management.Automation/engine/DataStoreAdapterProvider.cs +++ b/src/System.Management.Automation/engine/DataStoreAdapterProvider.cs @@ -105,7 +105,7 @@ namespace System.Management.Automation string psHome = null; try { - psHome = Utils.GetApplicationBase(Utils.DefaultPowerShellShellID); + psHome = Utils.DefaultPowerShellAppBase; } catch (System.Security.SecurityException) { diff --git a/src/System.Management.Automation/engine/InitialSessionState.cs b/src/System.Management.Automation/engine/InitialSessionState.cs index 5af8be7ebe..6ee87540b3 100644 --- a/src/System.Management.Automation/engine/InitialSessionState.cs +++ b/src/System.Management.Automation/engine/InitialSessionState.cs @@ -46,7 +46,7 @@ namespace System.Management.Automation.Runspaces { // Building the catalog is expensive, so force that to happen early on a background thread, and do so // on a file we are very likely to read anyway. - var pshome = Utils.GetApplicationBase(Utils.DefaultPowerShellShellID); + var pshome = Utils.DefaultPowerShellAppBase; var unused = SecuritySupport.IsProductBinary(Path.Combine(pshome, "Modules", "Microsoft.PowerShell.Utility", "Microsoft.PowerShell.Utility.psm1")); }); @@ -1597,7 +1597,7 @@ namespace System.Management.Automation.Runspaces private static void IncludePowerShellCoreFormats(InitialSessionState iss) { - string psHome = Utils.GetApplicationBase(Utils.DefaultPowerShellShellID); + string psHome = Utils.DefaultPowerShellAppBase; if (string.IsNullOrEmpty(psHome)) { return; @@ -4207,7 +4207,7 @@ namespace System.Management.Automation.Runspaces // We skip checking if the file exists when it's in $PSHOME because of magic // where we have the former contents of those files built into the engine directly. - var psHome = Utils.GetApplicationBase(Utils.DefaultPowerShellShellID); + var psHome = Utils.DefaultPowerShellAppBase; foreach (string file in psSnapInInfo.Types) { diff --git a/src/System.Management.Automation/engine/Modules/ImportModuleCommand.cs b/src/System.Management.Automation/engine/Modules/ImportModuleCommand.cs index 865a3bb08c..0764124c19 100644 --- a/src/System.Management.Automation/engine/Modules/ImportModuleCommand.cs +++ b/src/System.Management.Automation/engine/Modules/ImportModuleCommand.cs @@ -1768,11 +1768,11 @@ namespace Microsoft.PowerShell.Commands { if (m.Name.Equals(moduleName, StringComparison.OrdinalIgnoreCase)) { - m.SetModuleBase(Utils.GetApplicationBase(Utils.DefaultPowerShellShellID)); + m.SetModuleBase(Utils.DefaultPowerShellAppBase); // Also set ModuleBase for nested modules of Engine modules foreach (var nestedModule in m.NestedModules) { - nestedModule.SetModuleBase(Utils.GetApplicationBase(Utils.DefaultPowerShellShellID)); + nestedModule.SetModuleBase(Utils.DefaultPowerShellAppBase); } } } @@ -1781,11 +1781,11 @@ namespace Microsoft.PowerShell.Commands { if (m.Name.Equals(moduleName, StringComparison.OrdinalIgnoreCase)) { - m.SetModuleBase(Utils.GetApplicationBase(Utils.DefaultPowerShellShellID)); + m.SetModuleBase(Utils.DefaultPowerShellAppBase); // Also set ModuleBase for nested modules of Engine modules foreach (var nestedModule in m.NestedModules) { - nestedModule.SetModuleBase(Utils.GetApplicationBase(Utils.DefaultPowerShellShellID)); + nestedModule.SetModuleBase(Utils.DefaultPowerShellAppBase); } } } diff --git a/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs b/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs index b6aa270c9b..6490a800f7 100644 --- a/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs +++ b/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs @@ -2768,19 +2768,19 @@ namespace Microsoft.PowerShell.Commands } if (scriptsToProcess != null) - { - Version savedBaseMinimumVersion = BaseMinimumVersion; - Version savedBaseMaximumVersion = BaseMaximumVersion; - Version savedBaseRequiredVersion = BaseRequiredVersion; + { + Version savedBaseMinimumVersion = BaseMinimumVersion; + Version savedBaseMaximumVersion = BaseMaximumVersion; + Version savedBaseRequiredVersion = BaseRequiredVersion; Guid? savedBaseGuid = BaseGuid; - try - { - BaseMinimumVersion = null; - BaseMaximumVersion = null; - BaseRequiredVersion = null; - BaseGuid = null; - + try + { + BaseMinimumVersion = null; + BaseMaximumVersion = null; + BaseRequiredVersion = null; + BaseGuid = null; + foreach (string scriptFile in scriptsToProcess) { bool found = false; @@ -2812,14 +2812,14 @@ namespace Microsoft.PowerShell.Commands module.ExportedAliases[detectedAlias].Definition); } } - } - } - finally - { - BaseMinimumVersion = savedBaseMinimumVersion; - BaseMaximumVersion = savedBaseMaximumVersion; - BaseRequiredVersion = savedBaseRequiredVersion; - BaseGuid = savedBaseGuid; + } + } + finally + { + BaseMinimumVersion = savedBaseMinimumVersion; + BaseMaximumVersion = savedBaseMaximumVersion; + BaseRequiredVersion = savedBaseRequiredVersion; + BaseGuid = savedBaseGuid; } } @@ -4123,10 +4123,10 @@ namespace Microsoft.PowerShell.Commands Dictionary> requiredModules = new Dictionary>(new ModuleSpecificationComparer()); if (currentModule != null) { - requiredModules.Add(new ModuleSpecification(currentModule), new List { requiredModuleSpecification }); + requiredModules.Add(new ModuleSpecification(currentModule), new List { requiredModuleSpecification }); } - if (requiredModuleSpecification != null) - { + if (requiredModuleSpecification != null) + { requiredModules.Add(requiredModuleSpecification, new List(requiredModuleInfo.RequiredModulesSpecification)); } @@ -4498,13 +4498,13 @@ namespace Microsoft.PowerShell.Commands // Only add if this required module has nested required modules (meaning, it could lead to a circular reference) if (list.Count > 0) { - nonCyclicRequiredModules.Add(requiredModuleSpecification, list); - // We always need to check against the module specification and not the file name - if (HasRequiredModulesCyclicReference(requiredModuleSpecification, list, availableModules, nonCyclicRequiredModules, out error)) - { - return true; + nonCyclicRequiredModules.Add(requiredModuleSpecification, list); + // We always need to check against the module specification and not the file name + if (HasRequiredModulesCyclicReference(requiredModuleSpecification, list, availableModules, nonCyclicRequiredModules, out error)) + { + return true; } - } + } } } } @@ -4680,7 +4680,7 @@ namespace Microsoft.PowerShell.Commands if (listOfStrings != null) { - var psHome = Utils.GetApplicationBase(Utils.DefaultPowerShellShellID); + var psHome = Utils.DefaultPowerShellAppBase; string alternateDirToCheck = null; if (moduleBase.StartsWith(psHome, StringComparison.OrdinalIgnoreCase)) { diff --git a/src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs b/src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs index 7e684260b1..5848b30999 100644 --- a/src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs +++ b/src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs @@ -557,7 +557,7 @@ namespace System.Management.Automation try { - string psHome = Utils.GetApplicationBase(Utils.DefaultPowerShellShellID); + string psHome = Utils.DefaultPowerShellAppBase; if (!string.IsNullOrEmpty(psHome)) { // Win8: 584267 Powershell Modules are listed twice in x86, and cannot be removed diff --git a/src/System.Management.Automation/engine/Modules/ModuleUtils.cs b/src/System.Management.Automation/engine/Modules/ModuleUtils.cs index d16c6ee347..9226431be3 100644 --- a/src/System.Management.Automation/engine/Modules/ModuleUtils.cs +++ b/src/System.Management.Automation/engine/Modules/ModuleUtils.cs @@ -410,7 +410,7 @@ namespace System.Management.Automation.Internal tempModuleInfo = new PSModuleInfo(moduleShortName, modulePath, null, null); if (InitialSessionState.IsEngineModule(moduleShortName)) { - tempModuleInfo.SetModuleBase(Utils.GetApplicationBase(Utils.DefaultPowerShellShellID)); + tempModuleInfo.SetModuleBase(Utils.DefaultPowerShellAppBase); } //moduleVersionRequired is bypassed by FullyQualifiedModule from calling method. This is the only place where guid will be involved. diff --git a/src/System.Management.Automation/engine/TypeTable.cs b/src/System.Management.Automation/engine/TypeTable.cs index 5c7d9c7614..41ae3c93f9 100644 --- a/src/System.Management.Automation/engine/TypeTable.cs +++ b/src/System.Management.Automation/engine/TypeTable.cs @@ -3440,8 +3440,7 @@ namespace System.Management.Automation.Runspaces string typesFilePath = string.Empty; string typesV3FilePath = string.Empty; - string shellId = Utils.DefaultPowerShellShellID; - var psHome = Utils.GetApplicationBase(shellId); + var psHome = Utils.DefaultPowerShellAppBase; if (!string.IsNullOrEmpty(psHome)) { typesFilePath = Path.Combine(psHome, "types.ps1xml"); @@ -4404,7 +4403,7 @@ namespace System.Management.Automation.Runspaces var result = false; var errorCount = errors.Count; - var psHome = Utils.GetApplicationBase(Utils.DefaultPowerShellShellID); + var psHome = Utils.DefaultPowerShellAppBase; if (string.Equals(Path.Combine(psHome, "types.ps1xml"), filePath, StringComparison.OrdinalIgnoreCase)) { ProcessTypeData(filePath, errors, Types_Ps1Xml.Get()); diff --git a/src/System.Management.Automation/engine/Utils.cs b/src/System.Management.Automation/engine/Utils.cs index 886163488b..5888155542 100644 --- a/src/System.Management.Automation/engine/Utils.cs +++ b/src/System.Management.Automation/engine/Utils.cs @@ -238,20 +238,12 @@ namespace System.Management.Automation } #endif - /// - /// Gets the application base for current monad version - /// - /// - /// applicationbase path for current monad version installation - /// - /// - /// if caller doesn't have permission to read the key - /// + internal static string DefaultPowerShellAppBase { get; } = GetApplicationBase(DefaultPowerShellShellID); + internal static string GetApplicationBase(string shellId) { #if CORECLR - // Use the location of SMA.dll as the application base - // Assembly.GetEntryAssembly and GAC are not in CoreCLR. + // Use the location of SMA.dll as the application base. Assembly assembly = typeof(PSObject).GetTypeInfo().Assembly; return Path.GetDirectoryName(assembly.Location); #else @@ -312,7 +304,7 @@ namespace System.Management.Automation List baseDirectories = new List(); // Retrieve the application base from the registry - string appBase = GetApplicationBase(DefaultPowerShellShellID); + string appBase = Utils.DefaultPowerShellAppBase; if (!string.IsNullOrEmpty(appBase)) { baseDirectories.Add(appBase); @@ -381,7 +373,7 @@ namespace System.Management.Automation /// internal static bool IsRunningFromSysWOW64() { - return Utils.GetApplicationBase(Utils.DefaultPowerShellShellID).Contains("SysWOW64"); + return DefaultPowerShellAppBase.Contains("SysWOW64"); } /// diff --git a/src/System.Management.Automation/engine/hostifaces/PowerShellProcessInstance.cs b/src/System.Management.Automation/engine/hostifaces/PowerShellProcessInstance.cs index 84ac1e4fbc..f0de5d625a 100644 --- a/src/System.Management.Automation/engine/hostifaces/PowerShellProcessInstance.cs +++ b/src/System.Management.Automation/engine/hostifaces/PowerShellProcessInstance.cs @@ -37,10 +37,10 @@ namespace System.Management.Automation.Runspaces static PowerShellProcessInstance() { #if UNIX - s_PSExePath = Path.Combine(Utils.GetApplicationBase(Utils.DefaultPowerShellShellID), + s_PSExePath = Path.Combine(Utils.DefaultPowerShellAppBase, "powershell"); #else - s_PSExePath = Path.Combine(Utils.GetApplicationBase(Utils.DefaultPowerShellShellID), + s_PSExePath = Path.Combine(Utils.DefaultPowerShellAppBase, "powershell.exe"); #endif } diff --git a/src/System.Management.Automation/engine/remoting/commands/CustomShellCommands.cs b/src/System.Management.Automation/engine/remoting/commands/CustomShellCommands.cs index 1407d11313..a342219a85 100644 --- a/src/System.Management.Automation/engine/remoting/commands/CustomShellCommands.cs +++ b/src/System.Management.Automation/engine/remoting/commands/CustomShellCommands.cs @@ -964,7 +964,7 @@ else } } - string destPath = System.IO.Path.Combine(Utils.GetApplicationBase(Utils.DefaultPowerShellShellID), "SessionConfig", + string destPath = System.IO.Path.Combine(Utils.DefaultPowerShellAppBase, "SessionConfig", shellName + "_" + sessionGuid.ToString() + StringLiterals.PowerShellDISCFileExtension); if (string.Equals(ProcessorArchitecture, "x86", StringComparison.OrdinalIgnoreCase)) { @@ -3414,7 +3414,7 @@ Set-PSSessionConfiguration $args[0] $args[1] $args[2] $args[3] $args[4] $args[5] _gmsaAccount = _configTable[ConfigFileConstants.GMSAAccount] as string; } - string destPath = System.IO.Path.Combine(Utils.GetApplicationBase(Utils.DefaultPowerShellShellID), "SessionConfig", + string destPath = System.IO.Path.Combine(Utils.DefaultPowerShellAppBase, "SessionConfig", shellName + "_" + sessionGuid.ToString() + StringLiterals.PowerShellDISCFileExtension); // If the config file with the same guid name already exists then it would be overwritten. diff --git a/src/System.Management.Automation/help/UpdateHelpCommand.cs b/src/System.Management.Automation/help/UpdateHelpCommand.cs index 3659485db5..d8e748612b 100644 --- a/src/System.Management.Automation/help/UpdateHelpCommand.cs +++ b/src/System.Management.Automation/help/UpdateHelpCommand.cs @@ -381,7 +381,7 @@ namespace Microsoft.PowerShell.Commands #if !CORECLR // Side-By-Side directories are not present in OneCore environments. if (IsSystemModule(module.ModuleName) && Environment.Is64BitOperatingSystem) { - string path = Utils.GetApplicationBase(Utils.DefaultPowerShellShellID).Replace("System32", "SysWOW64"); + string path = Utils.DefaultPowerShellAppBase.Replace("System32", "SysWOW64"); destPaths.Add(path); } diff --git a/src/System.Management.Automation/minishell/api/FormatAndTypeDataHelper.cs b/src/System.Management.Automation/minishell/api/FormatAndTypeDataHelper.cs index 2270b137ee..4af4b553ea 100644 --- a/src/System.Management.Automation/minishell/api/FormatAndTypeDataHelper.cs +++ b/src/System.Management.Automation/minishell/api/FormatAndTypeDataHelper.cs @@ -103,7 +103,7 @@ namespace System.Management.Automation.Runspaces Collection returnValue = new Collection(); string baseFolder = GetBaseFolder(runspaceConfiguration, independentErrors); - var psHome = Utils.GetApplicationBase(Utils.DefaultPowerShellShellID); + var psHome = Utils.DefaultPowerShellAppBase; // this hashtable will be used to check whether this is duplicated file for types or formats. HashSet fullFileNameSet = new HashSet(StringComparer.OrdinalIgnoreCase); diff --git a/src/System.Management.Automation/security/Authenticode.cs b/src/System.Management.Automation/security/Authenticode.cs index e8ed6e1dc7..2f3682d86f 100644 --- a/src/System.Management.Automation/security/Authenticode.cs +++ b/src/System.Management.Automation/security/Authenticode.cs @@ -386,7 +386,7 @@ namespace System.Management.Automation if (!Signature.CatalogApiAvailable.HasValue) { - string productFile = Path.Combine(Utils.GetApplicationBase(Utils.DefaultPowerShellShellID), "Modules\\Microsoft.PowerShell.Utility\\Microsoft.PowerShell.Utility.psm1"); + string productFile = Path.Combine(Utils.DefaultPowerShellAppBase, "Modules\\Microsoft.PowerShell.Utility\\Microsoft.PowerShell.Utility.psm1"); if (signature.Status != SignatureStatus.Valid) { if (string.Equals(filename, productFile, StringComparison.OrdinalIgnoreCase)) diff --git a/src/System.Management.Automation/singleshell/config/MshSnapinInfo.cs b/src/System.Management.Automation/singleshell/config/MshSnapinInfo.cs index cc9b1eabb1..ded9214632 100644 --- a/src/System.Management.Automation/singleshell/config/MshSnapinInfo.cs +++ b/src/System.Management.Automation/singleshell/config/MshSnapinInfo.cs @@ -896,7 +896,7 @@ namespace System.Management.Automation internal static void ReadRegistryInfo(out Version assemblyVersion, out string publicKeyToken, out string culture, out string architecture, out string applicationBase, out Version psVersion) { - applicationBase = Utils.GetApplicationBase(Utils.DefaultPowerShellShellID); + applicationBase = Utils.DefaultPowerShellAppBase; Dbg.Assert(!string.IsNullOrEmpty(applicationBase), string.Format(CultureInfo.CurrentCulture, "{0} is empty or null", RegistryStrings.MonadEngine_ApplicationBase)); diff --git a/src/System.Management.Automation/utils/PSTelemetryMethods.cs b/src/System.Management.Automation/utils/PSTelemetryMethods.cs index 05520d0695..18939da372 100644 --- a/src/System.Management.Automation/utils/PSTelemetryMethods.cs +++ b/src/System.Management.Automation/utils/PSTelemetryMethods.cs @@ -168,7 +168,7 @@ namespace Microsoft.PowerShell.Telemetry.Internal var companyName = foundModule.CompanyName; bool couldBeMicrosoftModule = (modulePath != null && - (modulePath.StartsWith(Utils.GetApplicationBase(Utils.DefaultPowerShellShellID), StringComparison.OrdinalIgnoreCase) || + (modulePath.StartsWith(Utils.DefaultPowerShellAppBase, StringComparison.OrdinalIgnoreCase) || // The following covers both 64 and 32 bit Program Files by assuming 32bit is just ...\Program Files + " (x86)" modulePath.StartsWith(Platform.GetFolderPath(Environment.SpecialFolder.ProgramFiles), StringComparison.OrdinalIgnoreCase))) || (companyName != null &&