From 8d783b011c1890cdaf28d2c71ca10120aca7e71a Mon Sep 17 00:00:00 2001 From: BiDuang Date: Thu, 30 Nov 2023 10:53:28 +0800 Subject: [PATCH 1/4] fix: Full support for runtime cross platform --- .github/workflows/codeql-analysis.yml | 2 +- .../Class/Helper/DeepJavaSearcher.cs | 51 +-- .../ProjBobcat/Class/Helper/GamePathHelper.cs | 20 +- .../Class/Helper/SystemInfoHelper.cs | 30 +- .../ProjBobcat/Class/Model/JvmRulesModel.cs | 4 +- ProjBobcat/ProjBobcat/Constants.cs | 72 +++-- .../Launch/GameCore/DefaultGameCore.cs | 5 +- .../Linux/DistributionHelper.Linux.cs | 3 + .../Platforms/Linux/FileHelper.Linux.cs | 3 + .../Platforms/Linux/SystemInfoHelper.Linux.cs | 304 +++++++++--------- .../Platforms/MacOS/FileHelper.MacOS.cs | 3 + .../Platforms/MacOS/SystemInfoHelper.MacOS.cs | 280 ++++++++-------- ProjBobcat/ProjBobcat/ProjBobcat.csproj | 35 +- 13 files changed, 405 insertions(+), 407 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 8a7bc416..d02ddc5b 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -39,7 +39,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/ProjBobcat/ProjBobcat/Class/Helper/DeepJavaSearcher.cs b/ProjBobcat/ProjBobcat/Class/Helper/DeepJavaSearcher.cs index 9c4c96f9..55d559f9 100644 --- a/ProjBobcat/ProjBobcat/Class/Helper/DeepJavaSearcher.cs +++ b/ProjBobcat/ProjBobcat/Class/Helper/DeepJavaSearcher.cs @@ -2,8 +2,6 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; -using System.Runtime.InteropServices; -using System.Runtime.Versioning; namespace ProjBobcat.Class.Helper; @@ -12,27 +10,34 @@ public static class DeepJavaSearcher public static async IAsyncEnumerable DeepSearch(string drive, string fileName) { var result = new HashSet(); - var psi = new ProcessStartInfo(Constants.WhereCommand) - { -#if WINDOWS - ArgumentList = + ProcessStartInfo psi; + if (OperatingSystem.IsWindows()) + psi = new ProcessStartInfo(Constants.WhereCommand) { - "/R", - $"{drive}\\", - fileName - }, -#elif OSX || LINUX - ArgumentList = + ArgumentList = + { + "/R", + $"{drive}\\", + fileName + }, + CreateNoWindow = true, + RedirectStandardError = true, + RedirectStandardOutput = true, + UseShellExecute = false + }; + else + psi = new ProcessStartInfo(Constants.WhereCommand) { - "/b", - fileName - }, -#endif - CreateNoWindow = true, - RedirectStandardError = true, - RedirectStandardOutput = true, - UseShellExecute = false - }; + ArgumentList = + { + "/b", + fileName + }, + CreateNoWindow = true, + RedirectStandardError = true, + RedirectStandardOutput = true, + UseShellExecute = false + }; var process = Process.Start(psi); var isFailed = false; @@ -67,7 +72,6 @@ public static async IAsyncEnumerable DeepSearch(string drive, string fil public static async IAsyncEnumerable DeepSearch() { -#if WINDOWS if (OperatingSystem.IsWindows()) { var drives = Platforms.Windows.SystemInfoHelper.GetLogicalDrives(); @@ -76,10 +80,9 @@ public static async IAsyncEnumerable DeepSearch() await foreach (var path in DeepSearch(drive, Constants.JavaExecutable)) yield return path; } -#elif OSX || LINUX + if (OperatingSystem.IsMacOS() || OperatingSystem.IsLinux()) await foreach (var path in DeepSearch(string.Empty, Constants.JavaExecutable)) yield return path; -#endif } } \ No newline at end of file diff --git a/ProjBobcat/ProjBobcat/Class/Helper/GamePathHelper.cs b/ProjBobcat/ProjBobcat/Class/Helper/GamePathHelper.cs index 0d69fc98..d223865d 100644 --- a/ProjBobcat/ProjBobcat/Class/Helper/GamePathHelper.cs +++ b/ProjBobcat/ProjBobcat/Class/Helper/GamePathHelper.cs @@ -138,17 +138,13 @@ public static string GetLauncherAccountPath() /// public static string OfficialLauncherGamePath() { -#if WINDOWS - var basePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); -#elif OSX - var path = Environment.GetFolderPath(Environment.SpecialFolder.Personal); - var basePath = Path.Combine(path, "Library", "Application Support"); -#elif LINUX - var basePath = Environment.GetFolderPath(Environment.SpecialFolder.Personal); -#endif - - basePath = Path.Combine(basePath, ".minecraft"); - - return basePath; + if (OperatingSystem.IsWindows()) + return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), ".minecraft"); + if (OperatingSystem.IsMacOS()) + return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "Library", + "Application Support", ".minecraft"); + if (OperatingSystem.IsLinux()) + return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), ".minecraft"); + return string.Empty; } } \ No newline at end of file diff --git a/ProjBobcat/ProjBobcat/Class/Helper/SystemInfoHelper.cs b/ProjBobcat/ProjBobcat/Class/Helper/SystemInfoHelper.cs index 6aac7c29..eac0e877 100644 --- a/ProjBobcat/ProjBobcat/Class/Helper/SystemInfoHelper.cs +++ b/ProjBobcat/ProjBobcat/Class/Helper/SystemInfoHelper.cs @@ -29,43 +29,40 @@ public static string GetSystemArch() [SupportedOSPlatform(nameof(OSPlatform.OSX))] public static bool IsRunningUnderTranslation() { -#if WINDOWS if (OperatingSystem.IsWindows()) return Platforms.Windows.SystemInfoHelper.IsRunningUnderTranslation(); -#elif OSX + if (OperatingSystem.IsMacOS()) return Platforms.MacOS.SystemInfoHelper.IsRunningUnderTranslation(); -#endif + return false; } - + public static CPUInfo? GetProcessorUsage() { -#if WINDOWS if (OperatingSystem.IsWindows()) return Platforms.Windows.SystemInfoHelper.GetWindowsCpuUsage(); -#elif OSX + if (OperatingSystem.IsMacOS()) return Platforms.MacOS.SystemInfoHelper.GetOSXCpuUsage(); -#elif LINUX + if (OperatingSystem.IsLinux()) return Platforms.Linux.SystemInfoHelper.GetLinuxCpuUsage(); -#endif + return null; } public static MemoryInfo? GetMemoryUsage() { -#if WINDOWS if (OperatingSystem.IsWindows()) return Platforms.Windows.SystemInfoHelper.GetWindowsMemoryStatus(); -#elif OSX + if (OperatingSystem.IsMacOS()) return Platforms.MacOS.SystemInfoHelper.GetOsxMemoryStatus(); -#elif LINUX + if (OperatingSystem.IsLinux()) return Platforms.Linux.SystemInfoHelper.GetLinuxMemoryStatus(); -#endif + return null; } @@ -79,20 +76,19 @@ public static async IAsyncEnumerable FindJava(bool fullSearch = false) if (fullSearch) await foreach (var path in DeepJavaSearcher.DeepSearch()) result.Add(path); - -#if WINDOWS + if (OperatingSystem.IsWindows()) foreach (var path in Platforms.Windows.SystemInfoHelper.FindJavaWindows()) result.Add(path); -#elif OSX + if (OperatingSystem.IsMacOS()) foreach (var path in Platforms.MacOS.SystemInfoHelper.FindJavaMacOS()) result.Add(path); -#elif LINUX + if (OperatingSystem.IsLinux()) foreach(var path in Platforms.Linux.SystemInfoHelper.FindJavaLinux()) result.Add(path); -#endif + foreach (var path in result) yield return path; foreach (var path in FindJavaInOfficialGamePath()) diff --git a/ProjBobcat/ProjBobcat/Class/Model/JvmRulesModel.cs b/ProjBobcat/ProjBobcat/Class/Model/JvmRulesModel.cs index 79f19c1b..e023cd5b 100644 --- a/ProjBobcat/ProjBobcat/Class/Model/JvmRulesModel.cs +++ b/ProjBobcat/ProjBobcat/Class/Model/JvmRulesModel.cs @@ -16,13 +16,13 @@ public bool IsAllow() { if (!string.IsNullOrEmpty(Name) && !Name.Equals(Constants.OsSymbol, StringComparison.OrdinalIgnoreCase)) return false; + if (!string.IsNullOrEmpty(Arch) && Arch != SystemInfoHelper.GetSystemArch()) return false; -#if WINDOWS + if (OperatingSystem.IsWindows()) if (!string.IsNullOrEmpty(Version) && Version != $"^{Platforms.Windows.SystemInfoHelper.GetWindowsMajorVersion()}\\.") return false; -#endif return true; } diff --git a/ProjBobcat/ProjBobcat/Constants.cs b/ProjBobcat/ProjBobcat/Constants.cs index 18204e2e..61cf84ea 100644 --- a/ProjBobcat/ProjBobcat/Constants.cs +++ b/ProjBobcat/ProjBobcat/Constants.cs @@ -1,26 +1,56 @@ -namespace ProjBobcat; +using System; +using System.Runtime.InteropServices; + +namespace ProjBobcat; public static class Constants { public const string FallBackVersion = "0.0.0"; -#if WINDOWS - public const string WhereCommand = "where"; - public const string JavaExecutable = "javaw.exe"; - public const string JavaExecutablePath = $"bin\\{JavaExecutable}"; - public const string JavaExecutableExtension = "exe"; - public const string OsSymbol = "windows"; -#elif OSX - public const string WhereCommand = "whereis"; - public const string JavaExecutable = "java"; - public const string JavaExecutablePath = $"Contents/Home/bin/{JavaExecutable}"; - public const string JavaExecutableExtension = "*"; - public const string OsSymbol = "osx"; -#elif LINUX - public const string WhereCommand = "whereis"; - public const string JavaExecutable = "java"; - public const string JavaExecutablePath = $"bin/{JavaExecutable}"; - public const string JavaExecutableExtension = "*"; - public const string OsSymbol = "linux"; -#endif -} + public static string WhereCommand => OperatingSystem.IsWindows() ? Windows.WhereCommand : Linux.WhereCommand; + public static string JavaExecutable => OperatingSystem.IsWindows() ? Windows.JavaExecutable : Linux.JavaExecutable; + + public static string JavaExecutableExtension => OperatingSystem.IsWindows() + ? Windows.JavaExecutableExtension + : Linux.JavaExecutableExtension; + + public static string JavaExecutablePath => RuntimeInformation.RuntimeIdentifier switch + { + "windows" => Windows.JavaExecutablePath, + "linux" => Linux.JavaExecutablePath, + "osx" => Osx.JavaExecutablePath, + _ => throw new PlatformNotSupportedException("Unknown operating system.") + }; + + public static string OsSymbol => RuntimeInformation.RuntimeIdentifier switch + { + "windows" => Windows.OsSymbol, + "linux" => Linux.OsSymbol, + "osx" => Osx.OsSymbol, + _ => throw new PlatformNotSupportedException("Unknown operating system.") + }; + + class Windows + { + public const string WhereCommand = "where"; + public const string JavaExecutable = "javaw.exe"; + public const string JavaExecutablePath = $"bin\\{JavaExecutable}"; + public const string JavaExecutableExtension = "exe"; + public const string OsSymbol = "windows"; + } + + class Linux + { + public const string WhereCommand = "whereis"; + public const string JavaExecutable = "java"; + public const string JavaExecutablePath = $"bin/{JavaExecutable}"; + public const string JavaExecutableExtension = "*"; + public const string OsSymbol = "linux"; + } + + class Osx : Linux + { + public new const string JavaExecutablePath = $"Contents/Home/bin/{JavaExecutable}"; + public new const string OsSymbol = "osx"; + } +} \ No newline at end of file diff --git a/ProjBobcat/ProjBobcat/DefaultComponent/Launch/GameCore/DefaultGameCore.cs b/ProjBobcat/ProjBobcat/DefaultComponent/Launch/GameCore/DefaultGameCore.cs index 4d002b40..402c8577 100644 --- a/ProjBobcat/ProjBobcat/DefaultComponent/Launch/GameCore/DefaultGameCore.cs +++ b/ProjBobcat/ProjBobcat/DefaultComponent/Launch/GameCore/DefaultGameCore.cs @@ -355,13 +355,12 @@ await Task.Run(() => do { if (launchWrapper.Process == null) break; - -#if WINDOWS + if (OperatingSystem.IsWindows() && OperatingSystem.IsWindowsVersionAtLeast(5)) _ = Windows.Win32.PInvoke.SetWindowText( new Windows.Win32.Foundation.HWND(launchWrapper.Process.MainWindowHandle), settings.WindowTitle); -#endif + } while (string.IsNullOrEmpty(launchWrapper.Process?.MainWindowTitle)); }); #pragma warning restore CS4014 // 由于此调用不会等待,因此在调用完成前将继续执行当前方法 diff --git a/ProjBobcat/ProjBobcat/Platforms/Linux/DistributionHelper.Linux.cs b/ProjBobcat/ProjBobcat/Platforms/Linux/DistributionHelper.Linux.cs index b9e2a4f1..07ed9a55 100644 --- a/ProjBobcat/ProjBobcat/Platforms/Linux/DistributionHelper.Linux.cs +++ b/ProjBobcat/ProjBobcat/Platforms/Linux/DistributionHelper.Linux.cs @@ -1,7 +1,10 @@ using System.IO; +using System.Runtime.InteropServices; +using System.Runtime.Versioning; namespace ProjBobcat.Platforms.Linux; +[SupportedOSPlatform(nameof(OSPlatform.Linux))] public static class DistributionHelper { public enum LinuxDistribution diff --git a/ProjBobcat/ProjBobcat/Platforms/Linux/FileHelper.Linux.cs b/ProjBobcat/ProjBobcat/Platforms/Linux/FileHelper.Linux.cs index 7b6a115c..3327df49 100644 --- a/ProjBobcat/ProjBobcat/Platforms/Linux/FileHelper.Linux.cs +++ b/ProjBobcat/ProjBobcat/Platforms/Linux/FileHelper.Linux.cs @@ -1,7 +1,10 @@ using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Runtime.Versioning; namespace ProjBobcat.Platforms.Linux; +[SupportedOSPlatform(nameof(OSPlatform.Linux))] public static class FileHelper { public static bool Chmod(string filePath, string permissions) diff --git a/ProjBobcat/ProjBobcat/Platforms/Linux/SystemInfoHelper.Linux.cs b/ProjBobcat/ProjBobcat/Platforms/Linux/SystemInfoHelper.Linux.cs index 0974e0e0..b03c84e2 100644 --- a/ProjBobcat/ProjBobcat/Platforms/Linux/SystemInfoHelper.Linux.cs +++ b/ProjBobcat/ProjBobcat/Platforms/Linux/SystemInfoHelper.Linux.cs @@ -1,186 +1,184 @@ using ProjBobcat.Class.Model; using System; -using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; +using System.Runtime.InteropServices; using System.Runtime.Versioning; -using System.Threading; -using System.Threading.Tasks; -namespace ProjBobcat.Platforms.Linux +namespace ProjBobcat.Platforms.Linux; + +[SupportedOSPlatform(nameof(OSPlatform.Linux))] +class SystemInfoHelper { - class SystemInfoHelper + /// + /// Get the system overall CPU usage percentage. + /// + /// The percentange value with the '%' sign. e.g. if the usage is 30.1234 %, + /// then it will return 30.12. + public static CPUInfo GetLinuxCpuUsage() { - /// - /// Get the system overall CPU usage percentage. - /// - /// The percentange value with the '%' sign. e.g. if the usage is 30.1234 %, - /// then it will return 30.12. - public static CPUInfo GetLinuxCpuUsage() + var info = new ProcessStartInfo { - var info = new ProcessStartInfo - { - FileName = "/bin/bash", - Arguments = "-c \"top -bn1\"", - RedirectStandardOutput = true - }; - - using var process = Process.Start(info); - - if(process == null) - return new CPUInfo - { - Name = "Overrall", - Usage = -1 - }; - - var output = process.StandardOutput.ReadToEnd(); - process.WaitForExit(); - - var usage = output - .Split('\n', StringSplitOptions.RemoveEmptyEntries) - .Select(l => l.Split(' ', StringSplitOptions.RemoveEmptyEntries)) - .Select(arr => double.TryParse(arr[8], out var outCpu) ? outCpu : 0) - .Sum(); - + FileName = "/bin/bash", + Arguments = "-c \"top -bn1\"", + RedirectStandardOutput = true + }; + + using var process = Process.Start(info); + + if (process == null) return new CPUInfo { Name = "Overrall", - Usage = usage / 100 + Usage = -1 }; - } - /// - /// 获取 系统的内存信息 - /// - /// - public static MemoryInfo GetLinuxMemoryStatus() - { - var info = new ProcessStartInfo - { - FileName = "/bin/bash", - Arguments = "-c \"free -m\"", - RedirectStandardOutput = true - }; + var output = process.StandardOutput.ReadToEnd(); + process.WaitForExit(); - using var process = Process.Start(info); - - if(process == null) - return new MemoryInfo - { - Total = -1, - Used = -1, - Free = -1, - Percentage = -1 - }; - - var output = process.StandardOutput.ReadToEnd(); - process.WaitForExit(); - // Console.WriteLine(output); - - var lines = output.Split('\n'); - var memory = lines[1].Split(" ", StringSplitOptions.RemoveEmptyEntries); - - var total = double.Parse(memory[1]); - var used = double.Parse(memory[2]); - var free = double.Parse(memory[3]); - var percentage = used / total; - - var metrics = new MemoryInfo - { - Total = total, - Used = used, - Free = free, - Percentage = percentage * 100 - }; + var usage = output + .Split('\n', StringSplitOptions.RemoveEmptyEntries) + .Select(l => l.Split(' ', StringSplitOptions.RemoveEmptyEntries)) + .Select(arr => double.TryParse(arr[8], out var outCpu) ? outCpu : 0) + .Sum(); - return metrics; - } + return new CPUInfo + { + Name = "Overrall", + Usage = usage / 100 + }; + } - public static IEnumerable FindJavaLinux() + /// + /// 获取 系统的内存信息 + /// + /// + public static MemoryInfo GetLinuxMemoryStatus() + { + var info = new ProcessStartInfo { - var distribution = DistributionHelper.GetSystemDistribution(); - var jvmPath = string.Empty switch - { - _ when Directory.Exists("/usr/lib/jvm") => "/usr/lib/jvm", - _ when Directory.Exists("/usr/lib64/jvm") => "/usr/lib64/jvm", - _ => string.Empty - }; - - if(string.IsNullOrEmpty(jvmPath)) return Enumerable.Empty(); + FileName = "/bin/bash", + Arguments = "-c \"free -m\"", + RedirectStandardOutput = true + }; - var subJvmDirectories = Directory.GetDirectories(jvmPath); + using var process = Process.Start(info); - return distribution switch + if (process == null) + return new MemoryInfo { - DistributionHelper.LinuxDistribution.Arch => FindJavaArchLinux(subJvmDirectories), - DistributionHelper.LinuxDistribution.Debian => FindJavaDebianLinux(subJvmDirectories), - DistributionHelper.LinuxDistribution.RedHat => FindJavaRedHatLinux(subJvmDirectories), - DistributionHelper.LinuxDistribution.OpenSuse => FindJavaSuseLinux(subJvmDirectories), - _ => FindJavaOtherLinux() + Total = -1, + Used = -1, + Free = -1, + Percentage = -1 }; - } - static IEnumerable FindJavaArchLinux(string[] paths) - { - return - from path in paths - where !path.Contains("default", StringComparison.OrdinalIgnoreCase) - select $"{path}/bin/java" - into result - where File.Exists(result) - select result; - } - - static IEnumerable FindJavaDebianLinux(string[] paths) + var output = process.StandardOutput.ReadToEnd(); + process.WaitForExit(); + // Console.WriteLine(output); + + var lines = output.Split('\n'); + var memory = lines[1].Split(" ", StringSplitOptions.RemoveEmptyEntries); + + var total = double.Parse(memory[1]); + var used = double.Parse(memory[2]); + var free = double.Parse(memory[3]); + var percentage = used / total; + + var metrics = new MemoryInfo { - return - from path in paths - select $"{path}/bin/java" - into result - where File.Exists(result) - select result; - } - - static IEnumerable FindJavaRedHatLinux(string[] paths) + Total = total, + Used = used, + Free = free, + Percentage = percentage * 100 + }; + + return metrics; + } + + public static IEnumerable FindJavaLinux() + { + var distribution = DistributionHelper.GetSystemDistribution(); + var jvmPath = string.Empty switch { - return - from path in paths - where !path.Contains("jre", StringComparison.OrdinalIgnoreCase) - select $"{path}/bin/java" - into result - where File.Exists(result) - select result; - } - - static IEnumerable FindJavaSuseLinux(string[] paths) + _ when Directory.Exists("/usr/lib/jvm") => "/usr/lib/jvm", + _ when Directory.Exists("/usr/lib64/jvm") => "/usr/lib64/jvm", + _ => string.Empty + }; + + if (string.IsNullOrEmpty(jvmPath)) return Enumerable.Empty(); + + var subJvmDirectories = Directory.GetDirectories(jvmPath); + + return distribution switch { - return - from path in paths - where !path.Contains("jre", StringComparison.OrdinalIgnoreCase) - select $"{path}/bin/java" - into result - where File.Exists(result) - select result; - } - - static IEnumerable FindJavaOtherLinux() + DistributionHelper.LinuxDistribution.Arch => FindJavaArchLinux(subJvmDirectories), + DistributionHelper.LinuxDistribution.Debian => FindJavaDebianLinux(subJvmDirectories), + DistributionHelper.LinuxDistribution.RedHat => FindJavaRedHatLinux(subJvmDirectories), + DistributionHelper.LinuxDistribution.OpenSuse => FindJavaSuseLinux(subJvmDirectories), + _ => FindJavaOtherLinux() + }; + } + + static IEnumerable FindJavaArchLinux(string[] paths) + { + return + from path in paths + where !path.Contains("default", StringComparison.OrdinalIgnoreCase) + select $"{path}/bin/java" + into result + where File.Exists(result) + select result; + } + + static IEnumerable FindJavaDebianLinux(string[] paths) + { + return + from path in paths + select $"{path}/bin/java" + into result + where File.Exists(result) + select result; + } + + static IEnumerable FindJavaRedHatLinux(string[] paths) + { + return + from path in paths + where !path.Contains("jre", StringComparison.OrdinalIgnoreCase) + select $"{path}/bin/java" + into result + where File.Exists(result) + select result; + } + + static IEnumerable FindJavaSuseLinux(string[] paths) + { + return + from path in paths + where !path.Contains("jre", StringComparison.OrdinalIgnoreCase) + select $"{path}/bin/java" + into result + where File.Exists(result) + select result; + } + + static IEnumerable FindJavaOtherLinux() + { + var jvmPath = string.Empty switch { - var jvmPath = string.Empty switch - { - _ when Directory.Exists("/usr/lib/jvm") => "/usr/lib/jvm", - _ when Directory.Exists("/usr/lib32/jvm") => "/usr/lib32/jvm", - _ => "/usr/lib64/jvm" - }; + _ when Directory.Exists("/usr/lib/jvm") => "/usr/lib/jvm", + _ when Directory.Exists("/usr/lib32/jvm") => "/usr/lib32/jvm", + _ => "/usr/lib64/jvm" + }; - foreach (var path in Directory.GetDirectories(jvmPath)) - { - var result = $"{path}/bin/java"; + foreach (var path in Directory.GetDirectories(jvmPath)) + { + var result = $"{path}/bin/java"; - if (File.Exists(result)) yield return result; - } + if (File.Exists(result)) yield return result; } } -} +} \ No newline at end of file diff --git a/ProjBobcat/ProjBobcat/Platforms/MacOS/FileHelper.MacOS.cs b/ProjBobcat/ProjBobcat/Platforms/MacOS/FileHelper.MacOS.cs index 5bf9fddd..0d453e44 100644 --- a/ProjBobcat/ProjBobcat/Platforms/MacOS/FileHelper.MacOS.cs +++ b/ProjBobcat/ProjBobcat/Platforms/MacOS/FileHelper.MacOS.cs @@ -1,7 +1,10 @@ using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Runtime.Versioning; namespace ProjBobcat.Platforms.MacOS; +[SupportedOSPlatform(nameof(OSPlatform.OSX))] public static class FileHelper { public static bool Chmod(string filePath, string permissions) diff --git a/ProjBobcat/ProjBobcat/Platforms/MacOS/SystemInfoHelper.MacOS.cs b/ProjBobcat/ProjBobcat/Platforms/MacOS/SystemInfoHelper.MacOS.cs index 0e65fcda..34cf672f 100644 --- a/ProjBobcat/ProjBobcat/Platforms/MacOS/SystemInfoHelper.MacOS.cs +++ b/ProjBobcat/ProjBobcat/Platforms/MacOS/SystemInfoHelper.MacOS.cs @@ -5,186 +5,184 @@ using System.IO; using System.Linq; using System.Runtime.InteropServices; +using System.Runtime.Versioning; using System.Text.RegularExpressions; -namespace ProjBobcat.Platforms.MacOS +namespace ProjBobcat.Platforms.MacOS; + +[SupportedOSPlatform(nameof(OSPlatform.OSX))] +static class SystemInfoHelper { - static class SystemInfoHelper + [DllImport("libc")] + static extern int sysctlbyname(string name, out int int_val, ref IntPtr length, IntPtr newp, IntPtr newlen); + + public static IEnumerable FindJavaMacOS() { - [DllImport ("libc")] - static extern int sysctlbyname (string name, out int int_val, ref IntPtr length, IntPtr newp, IntPtr newlen); - - public static IEnumerable FindJavaMacOS() - { - const string rootPath = "/Library/Java/JavaVirtualMachines"; + const string rootPath = "/Library/Java/JavaVirtualMachines"; - foreach (var dir in Directory.EnumerateDirectories(rootPath)) + foreach (var dir in Directory.EnumerateDirectories(rootPath)) + { + var filePath = $"{dir}/{Constants.JavaExecutablePath}"; + if (File.Exists(filePath)) { - var filePath = $"{dir}/{Constants.JavaExecutablePath}"; - if (File.Exists(filePath)) - { -#if NET7_0_OR_GREATER - var flag = File.GetUnixFileMode(filePath); - - if (flag.HasFlag(UnixFileMode.GroupExecute) && flag.HasFlag(UnixFileMode.UserExecute)) - yield return filePath; -#else + var flag = File.GetUnixFileMode(filePath); + + if (flag.HasFlag(UnixFileMode.GroupExecute) && flag.HasFlag(UnixFileMode.UserExecute)) yield return filePath; -#endif - } } } + } - /// - /// Get the system overall CPU usage percentage. - /// - /// The percentange value with the '%' sign. e.g. if the usage is 30.1234 %, - /// then it will return 30.12. - public static CPUInfo GetOSXCpuUsage() + /// + /// Get the system overall CPU usage percentage. + /// + /// The percentange value with the '%' sign. e.g. if the usage is 30.1234 %, + /// then it will return 30.12. + public static CPUInfo GetOSXCpuUsage() + { + var info = new ProcessStartInfo { - var info = new ProcessStartInfo - { - FileName = "/bin/bash", - Arguments = "-c \"top -l 1 | grep -E \"^CPU\"\"", - RedirectStandardOutput = true, - CreateNoWindow = false - }; + FileName = "/bin/bash", + Arguments = "-c \"top -l 1 | grep -E \"^CPU\"\"", + RedirectStandardOutput = true, + CreateNoWindow = false + }; - using var process = Process.Start(info); - - if (process == null) - { - return new CPUInfo - { - Name = "Overrall", - Usage = -1 - }; - } - - var output = process.StandardOutput?.ReadToEnd(); - process.WaitForExit(); - - if (string.IsNullOrEmpty(output)) - { - return new CPUInfo - { - Name = "Overrall", - Usage = -1 - }; - } - - var cpu = output.Split(' ', StringSplitOptions.RemoveEmptyEntries); - - var userUsage = double.TryParse(cpu[2].TrimEnd('%'), out var userOut) ? userOut : 0; - var sysUsage = double.TryParse(cpu[4].TrimEnd('%'), out var sysOut) ? sysOut : 0; - var totalUsage = userUsage + sysUsage; + using var process = Process.Start(info); + if (process == null) + { return new CPUInfo { Name = "Overrall", - Usage = totalUsage + Usage = -1 }; } - - private static ulong GetTotalMemory() + + var output = process.StandardOutput?.ReadToEnd(); + process.WaitForExit(); + + if (string.IsNullOrEmpty(output)) { - var info = new ProcessStartInfo + return new CPUInfo { - FileName = "/usr/sbin/sysctl", - Arguments = "hw.memsize", - RedirectStandardOutput = true + Name = "Overrall", + Usage = -1 }; - - using var process = Process.Start(info); - - if (process == null) return 0; - - var output = process.StandardOutput?.ReadToEnd(); - process.WaitForExit(); + } - if (string.IsNullOrEmpty(output)) return 0; + var cpu = output.Split(' ', StringSplitOptions.RemoveEmptyEntries); - var split = output.Split(' ', StringSplitOptions.RemoveEmptyEntries); - var value = split.Last(); + var userUsage = double.TryParse(cpu[2].TrimEnd('%'), out var userOut) ? userOut : 0; + var sysUsage = double.TryParse(cpu[4].TrimEnd('%'), out var sysOut) ? sysOut : 0; + var totalUsage = userUsage + sysUsage; - return ulong.TryParse(value, out var outVal) ? outVal : 0; - } + return new CPUInfo + { + Name = "Overrall", + Usage = totalUsage + }; + } - /// - /// 获取 系统的内存信息 - /// - /// - public static MemoryInfo GetOsxMemoryStatus() + private static ulong GetTotalMemory() + { + var info = new ProcessStartInfo { - var info = new ProcessStartInfo - { - FileName = "/bin/bash", - Arguments = $"-c \"vm_stat\"", - RedirectStandardOutput = true - }; + FileName = "/usr/sbin/sysctl", + Arguments = "hw.memsize", + RedirectStandardOutput = true + }; - using var process = Process.Start(info); + using var process = Process.Start(info); - if (process == null) - { - return new MemoryInfo - { - Total = -1, - Used = -1, - Free = -1, - Percentage = -1 - }; - } - - var output = process.StandardOutput.ReadToEnd(); - process.WaitForExit(); + if (process == null) return 0; - if (string.IsNullOrEmpty(output)) - { - return new MemoryInfo - { - Total = -1, - Used = -1, - Free = -1, - Percentage = -1 - }; - } + var output = process.StandardOutput?.ReadToEnd(); + process.WaitForExit(); - var split = output.Split('\n', StringSplitOptions.RemoveEmptyEntries); - var infoDic = split - .Skip(1) - .Select(line => line.Split(' ', StringSplitOptions.RemoveEmptyEntries)) - .Select(lineSplit => (lineSplit.Take(lineSplit.Length - 1), lineSplit.Last().TrimEnd('.'))) - .Select(pair => (string.Join(' ', pair.Item1).TrimEnd(':'), double.TryParse(pair.Item2, out var outVal) ? outVal : 0)) - .ToDictionary(pair => pair.Item1, pair2 => pair2.Item2); + if (string.IsNullOrEmpty(output)) return 0; - var pageSize = uint.TryParse(Regex.Match(split[0], "\\d+").Value, out var pageSizeOut) ? pageSizeOut : 0; - var active = (infoDic.TryGetValue("Pages active", out var activeOut) ? activeOut : 0) * pageSize; + var split = output.Split(' ', StringSplitOptions.RemoveEmptyEntries); + var value = split.Last(); - var used = active / Math.Pow(1024, 2); - var total = GetTotalMemory() / Math.Pow(1024, 2); - var free = total - used; - var percentage = used / total; + return ulong.TryParse(value, out var outVal) ? outVal : 0; + } + + /// + /// 获取 系统的内存信息 + /// + /// + public static MemoryInfo GetOsxMemoryStatus() + { + var info = new ProcessStartInfo + { + FileName = "/bin/bash", + Arguments = $"-c \"vm_stat\"", + RedirectStandardOutput = true + }; + + using var process = Process.Start(info); - var metrics = new MemoryInfo + if (process == null) + { + return new MemoryInfo { - Total = total, - Used = used, - Free = free, - Percentage = percentage * 100 + Total = -1, + Used = -1, + Free = -1, + Percentage = -1 }; + } + + var output = process.StandardOutput.ReadToEnd(); + process.WaitForExit(); - return metrics; + if (string.IsNullOrEmpty(output)) + { + return new MemoryInfo + { + Total = -1, + Used = -1, + Free = -1, + Percentage = -1 + }; } - public static bool IsRunningUnderTranslation() + var split = output.Split('\n', StringSplitOptions.RemoveEmptyEntries); + var infoDic = split + .Skip(1) + .Select(line => line.Split(' ', StringSplitOptions.RemoveEmptyEntries)) + .Select(lineSplit => (lineSplit.Take(lineSplit.Length - 1), lineSplit.Last().TrimEnd('.'))) + .Select(pair => (string.Join(' ', pair.Item1).TrimEnd(':'), + double.TryParse(pair.Item2, out var outVal) ? outVal : 0)) + .ToDictionary(pair => pair.Item1, pair2 => pair2.Item2); + + var pageSize = uint.TryParse(Regex.Match(split[0], "\\d+").Value, out var pageSizeOut) ? pageSizeOut : 0; + var active = (infoDic.TryGetValue("Pages active", out var activeOut) ? activeOut : 0) * pageSize; + + var used = active / Math.Pow(1024, 2); + var total = GetTotalMemory() / Math.Pow(1024, 2); + var free = total - used; + var percentage = used / total; + + var metrics = new MemoryInfo { - var size = (IntPtr)sizeof(int); - var res = sysctlbyname("sysctl.proc_translated", out var value, ref size, IntPtr.Zero, (IntPtr)0); + Total = total, + Used = used, + Free = free, + Percentage = percentage * 100 + }; - if (res != 0) return false; + return metrics; + } - return value == 1; - } + public static bool IsRunningUnderTranslation() + { + var size = (IntPtr)sizeof(int); + var res = sysctlbyname("sysctl.proc_translated", out var value, ref size, IntPtr.Zero, (IntPtr)0); + + if (res != 0) return false; + + return value == 1; } -} +} \ No newline at end of file diff --git a/ProjBobcat/ProjBobcat/ProjBobcat.csproj b/ProjBobcat/ProjBobcat/ProjBobcat.csproj index 47a46c27..83c26c40 100644 --- a/ProjBobcat/ProjBobcat/ProjBobcat.csproj +++ b/ProjBobcat/ProjBobcat/ProjBobcat.csproj @@ -1,39 +1,15 @@ - - - win-x64 - - Library - net8.0 + net8.0 + false CS8618,CS8619,CS8601,CS8602,CS8603,CS8604,CS8620,CS8622,CS8625,CS8765,CS8766,CS8767 true - true - true - - true - false - - - - - WINDOWS - - - OSX - - - LINUX - - - - true true @@ -109,15 +85,8 @@ resolved the issue that LaunchWrapper may not return the correct exit code - - - - - - - From ce52e221e2a89f5c5aed2bb3e2958dad4acc117d Mon Sep 17 00:00:00 2001 From: BiDuang Date: Thu, 30 Nov 2023 11:01:38 +0800 Subject: [PATCH 2/4] fix: Packages miss --- .github/workflows/pre-release.yml | 4 +--- ProjBobcat/ProjBobcat/ProjBobcat.csproj | 6 +----- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/workflows/pre-release.yml b/.github/workflows/pre-release.yml index 596e3ecb..82b116d8 100644 --- a/.github/workflows/pre-release.yml +++ b/.github/workflows/pre-release.yml @@ -33,9 +33,7 @@ jobs: id: previoustag uses: "WyriHaximus/github-action-get-previous-tag@v1" with: - fallback: 0.0.0 - - name: Fix version tag - run: echo ::set-env name=PREVIOUS_TAG::${{ steps.previoustag.outputs.tag }} + fallback: 1.0.0 - name: Restore packages run: dotnet restore ProjBobcat/ProjBobcat.sln - name: Build the project diff --git a/ProjBobcat/ProjBobcat/ProjBobcat.csproj b/ProjBobcat/ProjBobcat/ProjBobcat.csproj index 83c26c40..5b1c92d9 100644 --- a/ProjBobcat/ProjBobcat/ProjBobcat.csproj +++ b/ProjBobcat/ProjBobcat/ProjBobcat.csproj @@ -6,10 +6,6 @@ CS8618,CS8619,CS8601,CS8602,CS8603,CS8604,CS8620,CS8622,CS8625,CS8765,CS8766,CS8767 - - true - - true true @@ -72,7 +68,7 @@ resolved the issue that LaunchWrapper may not return the correct exit code 0.34.2 - + From d6e9063abab69bc8d7691c250822e681a5592484 Mon Sep 17 00:00:00 2001 From: BiDuang Date: Thu, 30 Nov 2023 11:13:30 +0800 Subject: [PATCH 3/4] fix: bad format for version string --- .github/workflows/pre-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pre-release.yml b/.github/workflows/pre-release.yml index 82b116d8..42bf16ca 100644 --- a/.github/workflows/pre-release.yml +++ b/.github/workflows/pre-release.yml @@ -39,6 +39,6 @@ jobs: - name: Build the project run: dotnet build ProjBobcat/ProjBobcat.sln -c Release --no-restore - name: Create the package - run: $tag="${{ steps.previoustag.outputs.tag }}".replace("v",""); dotnet pack ProjBobcat/ProjBobcat.sln -c Release -p:PackageVersion="$tag-(CI)${{ github.sha }}-beta" --no-build --no-restore + run: $tag="${{ steps.previoustag.outputs.tag }}".replace("v",""); dotnet pack ProjBobcat/ProjBobcat.sln -c Release -p:PackageVersion="$tag-CI${{ github.sha }}-beta" --no-build --no-restore - name: Publish the package to NuGet.org run: dotnet nuget push -k ${{secrets.NUGET_KEY}} -s https://api.nuget.org/v3/index.json "ProjBobcat/ProjBobcat/bin/Release/*.nupkg" From 64c518c092dc950a13170756264853eb9fa803b2 Mon Sep 17 00:00:00 2001 From: BiDuang Date: Thu, 30 Nov 2023 11:16:26 +0800 Subject: [PATCH 4/4] ci: Test build will not perform on master push because of auto pre-release workflow --- .github/workflows/test.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6e39b78d..e93e7997 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,8 +1,6 @@ name: test on: - push: - branches: [master] pull_request: branches: [master]