diff --git a/src/ST.Client.Desktop.Avalonia.App/Program.cs b/src/ST.Client.Desktop.Avalonia.App/Program.cs
index 498bbddd0..ab4291caf 100644
--- a/src/ST.Client.Desktop.Avalonia.App/Program.cs
+++ b/src/ST.Client.Desktop.Avalonia.App/Program.cs
@@ -24,6 +24,8 @@ namespace System.Application.UI
#if MAC
AppDelegate.Init(/*args*/);
FileSystemDesktopMac.InitFileSystem();
+#elif LINUX
+ FileSystemDesktopXDG.InitFileSystem();
#else
FileSystemDesktop.InitFileSystem();
#endif
diff --git a/src/ST.Client.Desktop.Linux/FileSystemDesktopXDG.cs b/src/ST.Client.Desktop.Linux/FileSystemDesktopXDG.cs
new file mode 100644
index 000000000..f0046b9c1
--- /dev/null
+++ b/src/ST.Client.Desktop.Linux/FileSystemDesktopXDG.cs
@@ -0,0 +1,99 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace System.Application
+{
+ ///
+ /// 适用于 Linux 的文件系统初始化
+ /// XDG Base Directory Specification
+ /// https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
+ /// https://wiki.archlinux.org/title/XDG_Base_Directory
+ ///
+ public sealed class FileSystemDesktopXDG : IOPath.FileSystemBase
+ {
+ private FileSystemDesktopXDG() => throw new NotSupportedException();
+
+ ///
+ public static void InitFileSystem()
+ {
+ var appDataPath = AppDataDirectory;
+ var cachePath = CacheDirectory;
+
+ var paths = new[] { appDataPath, cachePath, };
+ var dict_paths = paths.ToDictionary(x => x, Directory.Exists);
+
+ if (dict_paths.Values.All(x => !x))
+ {
+ var old_paths = new[] { FileSystemDesktop.AppDataDirectory, FileSystemDesktop.CacheDirectory, };
+ if (old_paths.All(Directory.Exists)) // 迁移之前根目录上的文件夹
+ {
+ for (int i = 0; i < old_paths.Length; i++)
+ {
+ var path = paths[i];
+ var old_path = old_paths[i];
+ Directory.Move(old_path, path);
+ dict_paths[path] = true;
+ }
+ }
+ }
+
+ foreach (var item in dict_paths)
+ {
+ if (!item.Value)
+ {
+ Directory.CreateDirectory(item.Key);
+ }
+ }
+
+ InitFileSystem(GetAppDataDirectory, GetCacheDirectory);
+ string GetAppDataDirectory() => appDataPath;
+ string GetCacheDirectory() => cachePath;
+ }
+
+ static string AppDataDirectory
+ {
+ get
+ {
+ var value = Environment.GetEnvironmentVariable(XDG_DATA_HOME);
+ if (!string.IsNullOrWhiteSpace(value))
+ {
+ return Path.Combine(value, Constants.HARDCODED_APP_NAME);
+ }
+ value = Environment.GetEnvironmentVariable(HOME);
+ if (!string.IsNullOrWhiteSpace(value))
+ {
+ return Path.Combine(value, ".local", "share", Constants.HARDCODED_APP_NAME);
+ }
+ throw new PlatformNotSupportedException();
+ }
+ }
+
+ static string CacheDirectory
+ {
+ get
+ {
+ var value = Environment.GetEnvironmentVariable(XDG_CACHE_HOME);
+ if (!string.IsNullOrWhiteSpace(value))
+ {
+ return Path.Combine(value, Constants.HARDCODED_APP_NAME);
+ }
+ value = Environment.GetEnvironmentVariable(HOME);
+ if (!string.IsNullOrWhiteSpace(value))
+ {
+ return Path.Combine(value, ".cache", Constants.HARDCODED_APP_NAME);
+ }
+ throw new PlatformNotSupportedException();
+ }
+ }
+
+ const string HOME = "$HOME";
+
+ const string XDG_DATA_HOME = "$XDG_DATA_HOME";
+
+ const string XDG_CACHE_HOME = "$XDG_CACHE_HOME";
+ }
+}
diff --git a/src/ST.Client/FileSystemDesktop.cs b/src/ST.Client/FileSystemDesktop.cs
index b441de920..541d50f25 100644
--- a/src/ST.Client/FileSystemDesktop.cs
+++ b/src/ST.Client/FileSystemDesktop.cs
@@ -13,29 +13,45 @@ namespace System.Application
{
private FileSystemDesktop() => throw new NotSupportedException();
- ///
- /// 初始化文件系统
- ///
- public static void InitFileSystem()
+ static string BaseDirectory
{
- //var appDataRootPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
- //if (string.IsNullOrWhiteSpace(appDataRootPath))
- //{
- // // 需要测试 macOS 和 linux 上 Environment.SpecialFolder.ApplicationData 返回的目录值
- // // 之前在 android 上测试过 Environment.GetFolderPath 有些枚举值返回的是空字符串 比如StartMenu
- // throw new ArgumentNullException(nameof(appDataRootPath));
- //}
- //appDataRootPath = Path.Combine(appDataRootPath, BuildConfig.APPLICATION_ID);
-
- var appDataRootPath =
+ get
+ {
+ var appDataRootPath =
#if NET35
WinFormsApplication.StartupPath;
#else
IOPath.BaseDirectory;
#endif
+ return appDataRootPath;
+ }
+ }
- var appDataPath = Path.Combine(appDataRootPath, IOPath.DirName_AppData);
- var cachePath = Path.Combine(appDataRootPath, IOPath.DirName_Cache);
+ public static string AppDataDirectory
+ {
+ get
+ {
+ var appDataPath = Path.Combine(BaseDirectory, IOPath.DirName_AppData);
+ return appDataPath;
+ }
+ }
+
+ public static string CacheDirectory
+ {
+ get
+ {
+ var cachePath = Path.Combine(BaseDirectory, IOPath.DirName_Cache);
+ return cachePath;
+ }
+ }
+
+ ///
+ /// 初始化文件系统
+ ///
+ public static void InitFileSystem()
+ {
+ var appDataPath = AppDataDirectory;
+ var cachePath = CacheDirectory;
IOPath.DirCreateByNotExists(appDataPath);
IOPath.DirCreateByNotExists(cachePath);
InitFileSystem(GetAppDataDirectory, GetCacheDirectory);