diff --git a/src/System.Management.Automation/engine/PropertyAccessor.cs b/src/System.Management.Automation/engine/PropertyAccessor.cs index 6a63302ad..15203fa24 100644 --- a/src/System.Management.Automation/engine/PropertyAccessor.cs +++ b/src/System.Management.Automation/engine/PropertyAccessor.cs @@ -134,7 +134,6 @@ namespace System.Management.Automation { private string psHomeConfigDirectory; private string appDataConfigDirectory; - private const string configDirectoryName = "Configuration"; private const string configFileName = "PowerShellProperties.json"; /// @@ -147,27 +146,50 @@ namespace System.Management.Automation internal JsonConfigFileAccessor() { // - // Initialize (and create if necessary) the system-wide configuration directory + // Sets the system-wide configuration directory // Assembly assembly = typeof(PSObject).GetTypeInfo().Assembly; - psHomeConfigDirectory = Path.Combine(Path.GetDirectoryName(assembly.Location), configDirectoryName); - - if (!Directory.Exists(psHomeConfigDirectory)) - { - Directory.CreateDirectory(psHomeConfigDirectory); - } + psHomeConfigDirectory = Path.GetDirectoryName(assembly.Location); // - // Initialize (and create if necessary) the per-user configuration directory + // Sets the per-user configuration directory // - appDataConfigDirectory = Path.Combine(Utils.GetUserSettingsDirectory(), configDirectoryName); - + appDataConfigDirectory = Utils.GetUserSettingsDirectory(); if (!Directory.Exists(appDataConfigDirectory)) { - Directory.CreateDirectory(appDataConfigDirectory); + try + { + Directory.CreateDirectory(appDataConfigDirectory); + } + catch (UnauthorizedAccessException) + { + // Do nothing now. This failure shouldn't block initialization + appDataConfigDirectory = null; + } } } + /// + /// Enables delayed creation of the user settings directory so it does + /// not interfere with PowerShell initialization + /// + /// Returns the directory if present or creatable. Throws otherwise. + private string GetAppDataConfigDirectory() + { + if (null == appDataConfigDirectory) + { + string tempAppDataConfigDir = Utils.GetUserSettingsDirectory(); + if (!Directory.Exists(tempAppDataConfigDir)) + { + Directory.CreateDirectory(tempAppDataConfigDir); + // Only assign it if creation succeeds. It will throw if it fails. + appDataConfigDirectory = tempAppDataConfigDir; + } + // Do not catch exceptions here. Let them flow up. + } + return appDataConfigDirectory; + } + /// /// This value is not writable via the API and must be set using a text editor. /// @@ -180,7 +202,7 @@ namespace System.Management.Automation // Defaults to system wide. if (PropertyScope.CurrentUser == scope) { - scopeDirectory = appDataConfigDirectory; + scopeDirectory = GetAppDataConfigDirectory(); } string fileName = Path.Combine(scopeDirectory, configFileName); @@ -215,7 +237,7 @@ namespace System.Management.Automation // Defaults to system wide. if(PropertyScope.CurrentUser == scope) { - scopeDirectory = appDataConfigDirectory; + scopeDirectory = GetAppDataConfigDirectory(); } string fileName = Path.Combine(scopeDirectory, configFileName); @@ -236,7 +258,7 @@ namespace System.Management.Automation // Defaults to system wide. if (PropertyScope.CurrentUser == scope) { - scopeDirectory = appDataConfigDirectory; + scopeDirectory = GetAppDataConfigDirectory(); } string fileName = Path.Combine(scopeDirectory, configFileName); @@ -251,7 +273,7 @@ namespace System.Management.Automation // Defaults to system wide. if (PropertyScope.CurrentUser == scope) { - scopeDirectory = appDataConfigDirectory; + scopeDirectory = GetAppDataConfigDirectory(); } string fileName = Path.Combine(scopeDirectory, configFileName);