diff --git a/src/ST.Client.Desktop.Avalonia.App/NotifyIconHelper.cs b/src/ST.Client.Desktop.Avalonia.App/NotifyIconHelper.cs index 45da0bbb1..c4e5c411d 100644 --- a/src/ST.Client.Desktop.Avalonia.App/NotifyIconHelper.cs +++ b/src/ST.Client.Desktop.Avalonia.App/NotifyIconHelper.cs @@ -246,7 +246,11 @@ namespace System.Application.UI { if (!OperatingSystem.IsLinux()) return; var fileName = AppHelper.ProgramPath + "_LinuxTrayIcon"; - if (!File.Exists(fileName)) return; + + var unixSetFileAccessResult = IDesktopPlatformService.Instance.UnixSetFileAccess(fileName, IDesktopPlatformService.UnixPermission.Combined755); + + if (unixSetFileAccessResult != IDesktopPlatformService.UnixSetFileAccessResult.Success) + return; Process pipeClient = new(); diff --git a/src/ST.Client.Desktop.Linux/ST.Client.Desktop.Linux.csproj b/src/ST.Client.Desktop.Linux/ST.Client.Desktop.Linux.csproj index 5f60b3705..cd7f2ea95 100644 --- a/src/ST.Client.Desktop.Linux/ST.Client.Desktop.Linux.csproj +++ b/src/ST.Client.Desktop.Linux/ST.Client.Desktop.Linux.csproj @@ -36,4 +36,8 @@ PreserveNewest + + + + \ No newline at end of file diff --git a/src/ST.Client.Desktop.Windows/Internals/NativeMethods.cs b/src/ST.Client.Desktop.Windows/Internals/NativeMethods.cs index 290ce62fd..fd13d601e 100644 --- a/src/ST.Client.Desktop.Windows/Internals/NativeMethods.cs +++ b/src/ST.Client.Desktop.Windows/Internals/NativeMethods.cs @@ -6,7 +6,7 @@ using System.Text; // ReSharper disable once CheckNamespace namespace System { - internal static class NativeMethods + internal static partial class NativeMethods { [DllImport("Avrt.dll", CharSet = CharSet.Unicode)] public static extern IntPtr AvSetMmThreadCharacteristics(string taskName, ref uint taskIndex); diff --git a/src/ST.Client.Desktop/Services/IDesktopPlatformService.UnixSetFileAccess.cs b/src/ST.Client.Desktop/Services/IDesktopPlatformService.UnixSetFileAccess.cs new file mode 100644 index 000000000..b4535139e --- /dev/null +++ b/src/ST.Client.Desktop/Services/IDesktopPlatformService.UnixSetFileAccess.cs @@ -0,0 +1,84 @@ +using System.IO; +using System.Runtime.InteropServices; +using System.Runtime.Versioning; + +namespace System.Application.Services +{ + partial interface IDesktopPlatformService + { + [Flags] + [SupportedOSPlatform("FreeBSD")] + [SupportedOSPlatform("Linux")] + [SupportedOSPlatform("MacOS")] + enum UnixPermission : ushort + { + OtherExecute = 0x1, + OtherWrite = 0x2, + OtherRead = 0x4, + GroupExecute = 0x8, + GroupWrite = 0x10, + GroupRead = 0x20, + UserExecute = 0x40, + UserWrite = 0x80, + UserRead = 0x100, + Combined755 = UserRead | UserWrite | UserExecute | GroupRead | GroupExecute | OtherRead | OtherExecute, + Combined777 = UserRead | UserWrite | UserExecute | GroupRead | GroupWrite | GroupExecute | OtherRead | OtherWrite | OtherExecute + } + + [SupportedOSPlatform("FreeBSD")] + [SupportedOSPlatform("Linux")] + [SupportedOSPlatform("MacOS")] + UnixSetFileAccessResult UnixSetFileAccess(string? path, UnixPermission permission) + { + if (!OperatingSystem2.IsFreeBSD && + !OperatingSystem2.IsLinux && + !OperatingSystem2.IsMacOS) + throw new PlatformNotSupportedException(); + + if (string.IsNullOrEmpty(path)) + return UnixSetFileAccessResult.PathIsNullOrEmpty; + + if (!File.Exists(path) && !Directory.Exists(path)) + return UnixSetFileAccessResult.PathInvalid; + + var result = Chmod(path, (int)permission); + if (result == 0) return UnixSetFileAccessResult.Success; + + var lastError = Marshal.GetLastWin32Error(); + Log.Error(TAG, + "UnixSetFileAccess Fail, permission:{3}, result: {0}, lastError: {1}, path: {2}", + result, + lastError, + path, + permission); + + return (UnixSetFileAccessResult)result; + } + +#pragma warning disable CA2101 // False positive, we can't use unicode charset on Unix, and it uses UTF-8 by default anyway + /// + /// + /// + /// + /// + /// 0 on success, -1 on failure + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + [DllImport("libc", EntryPoint = "chmod", SetLastError = true)] + [SupportedOSPlatform("FreeBSD")] + [SupportedOSPlatform("Linux")] + [SupportedOSPlatform("MacOS")] + private static extern int Chmod(string path, int mode); +#pragma warning restore CA2101 // False positive, we can't use unicode charset on Unix, and it uses UTF-8 by default anyway + + [SupportedOSPlatform("FreeBSD")] + [SupportedOSPlatform("Linux")] + [SupportedOSPlatform("MacOS")] + enum UnixSetFileAccessResult + { + PathIsNullOrEmpty = -3, + PathInvalid, + Failure, + Success, + } + } +} \ No newline at end of file