diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs
index 61a4012d6..8c04e0fcb 100644
--- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs
+++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs
@@ -185,14 +185,18 @@ namespace Microsoft.PowerShell
{
profileDir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) +
@"\Microsoft\Windows\PowerShell";
- } else
+ }
+
+ else
{
- profileDir = System.IO.Path.Combine(Environment.GetEnvironmentVariable("HOME"), ".powershell");
+ //check if the user has set an XDG path in their environment variables
+ profileDir = Platform.SelectProductNameForDirectory("profile");
}
-
- if (!Directory.Exists(profileDir))
+
+ if (!Directory.Exists(profileDir)) //xdg value may have been set but not a valid directory
{
- Directory.CreateDirectory(profileDir);
+ Console.WriteLine("The selected directory for the profile does not exist. Using the default path.");
+ profileDir = Platform.SelectProductNameForDirectory("default");
}
ClrFacade.SetProfileOptimizationRoot(profileDir);
}
@@ -268,7 +272,6 @@ namespace Microsoft.PowerShell
: "StartupProfileData-NonInteractive");
exitCode = theConsoleHost.Run(cpp, !string.IsNullOrEmpty(preStartWarning));
}
-
}
finally
{
diff --git a/src/Microsoft.PowerShell.PSReadLine/Cmdlets.cs b/src/Microsoft.PowerShell.PSReadLine/Cmdlets.cs
index 3210a8965..fb9145314 100644
--- a/src/Microsoft.PowerShell.PSReadLine/Cmdlets.cs
+++ b/src/Microsoft.PowerShell.PSReadLine/Cmdlets.cs
@@ -178,14 +178,25 @@ namespace Microsoft.PowerShell
}
else
{
+ //PSReadline does not have access to Utils.CorePSPlatform. Must set PSReadline path seperately
+ string modulepath = System.Environment.GetEnvironmentVariable("XDG_CACHE_HOME");
+
+ if (String.IsNullOrEmpty(modulepath))
+ {
+ modulepath = System.IO.Path.Combine(
+ Environment.GetEnvironmentVariable("HOME"),
+ ".config/powershell/modules");
+ }
+
HistorySavePath = System.IO.Path.Combine(
Environment.GetEnvironmentVariable("HOME"),
- ".powershell",
+ modulepath,
"PSReadLine",
hostName + "_history.txt");
- }
-#else
- HistorySavePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
+
+ }
+ #else
+ HistorySavePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
+ @"\Microsoft\Windows\PowerShell\PSReadline\" + hostName + "_history.txt";
#endif
CommandValidationHandler = null;
@@ -205,7 +216,7 @@ namespace Microsoft.PowerShell
"Where-Object", "?", "where",
};
}
-
+
public EditMode EditMode { get; set; }
public string ContinuationPrompt { get; set; }
diff --git a/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs b/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs
index 34623fc1b..9e2d40541 100644
--- a/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs
+++ b/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs
@@ -96,8 +96,57 @@ namespace System.Management.Automation
"WSMan.format.ps1xml"
};
- // directory location of PowerShell for profile loading
- public static string ProductNameForDirectory = ".powershell";
+ // function for choosing directory location of PowerShell for profile loading
+ public static string SelectProductNameForDirectory (string dir){
+
+ string xdgconfighome = System.Environment.GetEnvironmentVariable("XDG_CONFIG_HOME");
+ string xdgdatahome = System.Environment.GetEnvironmentVariable("XDG_DATA_HOME");
+ string xdgcachehome = System.Environment.GetEnvironmentVariable("XDG_CACHE_HOME");
+
+
+ //the user has set XDG_CONFIG_HOME corrresponding to profile path
+ if (!String.IsNullOrEmpty(xdgconfighome) && dir == "profile")
+ {
+ return xdgconfighome;
+ }
+
+ //the user has set XDG_DATA_HOME corresponding to module path
+ if (!String.IsNullOrEmpty(xdgdatahome) && dir == "modules")
+ {
+ return xdgdatahome;
+ }
+
+ //the user has set XDG_CACHE_HOME
+ if (!String.IsNullOrEmpty(xdgcachehome) && dir == "history")
+ {
+ return xdgcachehome;
+ }
+
+ if (dir == "default")
+ {
+ return @".config/powershell";
+ }
+ //the user has set XDG_DATA_HOME
+ else //xdg values have not been set
+ {
+ if (dir == "profile" || dir == "history")
+ {
+ return @".config/powershell"; //default on Linux
+ }
+ if (dir == "modules")
+ {
+ if (!Directory.Exists(@".config/powershell/modules"))
+ {
+ Directory.CreateDirectory(@".config/powershell/modules");
+
+ }
+
+ return @".config/powershell/modules"; //default on Linux
+ }
+
+ return @".config/powershell";
+ }
+ }
// ComObjectType is null on CoreCLR for Linux since there is
// no COM support on Linux
diff --git a/src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs b/src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs
index 129fd8db5..46bd51a21 100644
--- a/src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs
+++ b/src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs
@@ -548,12 +548,7 @@ namespace System.Management.Automation
/// personal module path
internal static string GetPersonalModulePath()
{
- string personalModuleRoot = Path.Combine(
- Path.Combine(
- Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
- Utils.ProductNameForDirectory),
- Utils.ModuleDirectory);
-
+ string personalModuleRoot = Platform.SelectProductNameForDirectory("modules");
return personalModuleRoot;
}
@@ -597,6 +592,7 @@ namespace System.Management.Automation
psHome = psHome.ToLowerInvariant().Replace("\\syswow64\\", "\\system32\\");
}
Interlocked.CompareExchange(ref SystemWideModulePath, Path.Combine(psHome, Utils.ModuleDirectory), null);
+
}
return SystemWideModulePath;
diff --git a/src/System.Management.Automation/engine/Utils.cs b/src/System.Management.Automation/engine/Utils.cs
index 8c4f55e7d..3e6857d1b 100644
--- a/src/System.Management.Automation/engine/Utils.cs
+++ b/src/System.Management.Automation/engine/Utils.cs
@@ -606,13 +606,13 @@ namespace System.Management.Automation
/// Profile uses this to control profile loading.
///
internal static string ProductNameForDirectory =
- Platform.IsWindows ? "WindowsPowerShell" : Platform.ProductNameForDirectory;
+ Platform.IsWindows ? "WindowsPowerShell" : Platform.SelectProductNameForDirectory("profile");
///
/// The name of the subdirectory that contains packages.
///
internal static string ModuleDirectory = "Modules";
-
+
///
/// The partial path to the DSC module directory
///
diff --git a/src/System.Management.Automation/engine/hostifaces/HostUtilities.cs b/src/System.Management.Automation/engine/hostifaces/HostUtilities.cs
index 8783240ec..aef980161 100644
--- a/src/System.Management.Automation/engine/hostifaces/HostUtilities.cs
+++ b/src/System.Management.Automation/engine/hostifaces/HostUtilities.cs
@@ -152,6 +152,7 @@ namespace System.Management.Automation
{
continue;
}
+
command = new PSCommand();
command.AddCommand(profilePath, false);
commands.Add(command);
@@ -186,7 +187,14 @@ namespace System.Management.Automation
{
basePath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
basePath = IO.Path.Combine(basePath, Utils.ProductNameForDirectory);
+
+ //If the profile path doesn't exist, create it.
+ if (!System.IO.Directory.Exists(basePath))
+ {
+ System.IO.Directory.CreateDirectory(basePath);
+ }
}
+
else
{
basePath = GetAllUsersFolderPath(shellId);
@@ -198,7 +206,6 @@ namespace System.Management.Automation
string profileName = useTestProfile ? "profile_test.ps1" : "profile.ps1";
-
if (!string.IsNullOrEmpty(shellId))
{
profileName = shellId + "_" + profileName;