소스 검색

Improved exception message about library incompatibily on the Linux system with legacy glibc version

Marcin Ziąbek 9 달 전
부모
커밋
c42f5ebb37
2개의 변경된 파일67개의 추가작업 그리고 30개의 파일을 삭제
  1. 16 1
      Source/QuestPDF/Helpers/NativeDependencyCompatibilityChecker.cs
  2. 51 29
      Source/QuestPDF/Helpers/NativeDependencyProvider.cs

+ 16 - 1
Source/QuestPDF/Helpers/NativeDependencyCompatibilityChecker.cs

@@ -6,6 +6,8 @@ namespace QuestPDF.Helpers
 {
     internal class NativeDependencyCompatibilityChecker
     {
+        private static readonly Version RequiredGlibcVersionOnLinux = Version.Parse("2.29");
+        
         private bool IsCompatibilityChecked { get; set; } = false;
 
         public Action ExecuteNativeCode { get; set; } = () => { };
@@ -74,7 +76,20 @@ namespace QuestPDF.Helpers
                     message += $"{paragraph}{hint}";
 
                 if (isRuntimeSupported)
-                    message += $"{paragraph}If the problem persists, it may mean that your current operating system distribution is outdated. For optimal compatibility, please consider updating it to a more recent version.";
+                {
+                    var glibcVersion = NativeDependencyProvider.GetGlibcVersion();
+
+                    if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && glibcVersion < RequiredGlibcVersionOnLinux)
+                    {
+                        message += $"{paragraph}Please consider updating your operating system distribution. " +
+                                   $"Current GLIBC version: {glibcVersion}. " +
+                                   $"The minimum required version is {RequiredGlibcVersionOnLinux}. ";
+                    }
+                    else
+                    {
+                        message += $"{paragraph}If the problem persists, it may mean that your current operating system distribution is outdated. For optimal compatibility, please consider updating it to a more recent version.";
+                    }
+                }
                 
                 throw new Exception(message, innerException);
             }

+ 51 - 29
Source/QuestPDF/Helpers/NativeDependencyProvider.cs

@@ -3,6 +3,7 @@ using System.Diagnostics;
 using System.IO;
 using System.Linq;
 using System.Runtime.InteropServices;
+using System.Text.RegularExpressions;
 
 namespace QuestPDF.Helpers;
 
@@ -101,43 +102,64 @@ internal static class NativeDependencyProvider
         {
             return RuntimeInformation.ProcessArchitecture.ToString().ToLower();
         }
+    }
+    
+    private static string? ExecuteLddCommand()
+    {
+        if (!RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+            return null;
         
-        static bool IsLinuxMusl()
+        try
         {
-            if (!RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
-                return false;
-            
-            try
-            { 
-                var processStartInfo = new ProcessStartInfo
-                {
-                    FileName = "ldd",
-                    RedirectStandardOutput = true,
-                    RedirectStandardError = true,
-                    UseShellExecute = false,
-                    CreateNoWindow = true
-                };
-                
-                using var process = Process.Start(processStartInfo);
+            var processStartInfo = new ProcessStartInfo
+            {
+                FileName = "ldd",
+                Arguments = "--version",
+                RedirectStandardOutput = true,
+                RedirectStandardError = true,
+                UseShellExecute = false,
+                CreateNoWindow = true
+            };
                 
-                if (process == null)
-                    return false;
+            using var process = Process.Start(processStartInfo);
                 
-                process.Start();
+            if (process == null)
+                return null;
                 
-                var standardOutputText = process.StandardOutput.ReadToEnd();
-                var standardErrorText = process.StandardError.ReadToEnd();
+            var standardOutputText = process.StandardOutput.ReadToEnd();
+            var standardErrorText = process.StandardError.ReadToEnd();
                 
-                process.WaitForExit();
+            process.WaitForExit();
                 
-                var outputText = standardOutputText + standardErrorText;
-                return outputText.IndexOf("musl", StringComparison.InvariantCultureIgnoreCase) >= 0;
-            }
-            catch
-            {
-                return false;
-            }
+            return standardOutputText + standardErrorText;
         }
+        catch
+        {
+            return null;
+        }
+    }
+
+    private static bool IsLinuxMusl()
+    {
+        var lddCommandOutput = ExecuteLddCommand() ?? string.Empty;
+        var containsMuslText = lddCommandOutput.IndexOf("musl", StringComparison.InvariantCultureIgnoreCase) >= 0;
+        return containsMuslText;
+    }
+
+    public static Version? GetGlibcVersion()
+    {
+        var lddCommandOutput = ExecuteLddCommand() ?? string.Empty;
+        var match = Regex.Match(lddCommandOutput, @"ldd \(.+\) (?<version>[1-9]\.[0-9]{2})");
+    
+        if (!match.Success)
+            return null;
+
+        var versionGroup = match.Groups["version"];
+        
+        if (!versionGroup.Success)
+            return null;
+    
+        return Version.TryParse(versionGroup.Value, out var parsedVersion) ? parsedVersion : null;
     }
 
     private static void CopyFileIfNewer(string sourcePath, string targetPath)