From 87aac04585261b653f3d5a30b3e9ebff9166061b Mon Sep 17 00:00:00 2001 From: David Sungaila Date: Wed, 11 Oct 2023 14:27:20 +0200 Subject: [PATCH 1/2] Fix for Android release builds not loading libpdfium correctly --- src/Console/Console.csproj | 2 +- src/PDFtoImage/PDFtoImage.csproj | 15 +++--- src/PDFtoImage/PdfiumViewer/NativeMethods.cs | 56 +++++++++++++------- src/WebConverter/WebConverter.csproj | 6 +-- 4 files changed, 48 insertions(+), 31 deletions(-) diff --git a/src/Console/Console.csproj b/src/Console/Console.csproj index 47f75226..5cf1137b 100644 --- a/src/Console/Console.csproj +++ b/src/Console/Console.csproj @@ -7,7 +7,7 @@ PDFtoImage.Console PDFtoImage.Console PDFtoImage.Console.Program - 2.4.1 + 2.4.2 Debug;Release;ReleaseSigned diff --git a/src/PDFtoImage/PDFtoImage.csproj b/src/PDFtoImage/PDFtoImage.csproj index aeb75f33..83d3029f 100644 --- a/src/PDFtoImage/PDFtoImage.csproj +++ b/src/PDFtoImage/PDFtoImage.csproj @@ -12,7 +12,7 @@ - 2.4.1 + 2.4.2 David Sungaila false @@ -21,8 +21,7 @@ https://github.com/sungaila/PDFtoImage https://raw.githubusercontent.com/sungaila/PDFtoImage/master/etc/Icon_128.png A .NET library to render PDF files into images. - - Fixed an issue where password protected PDF files could not be opened. -- Added PDF specific Exception classes (e.g. PdfPasswordProtectedException). + - Fixed an issue where Android release builds would fail to load libpdfium. PDF Bitmap Image Convert Conversion C# PDFium SkiaSharp Skia PNG JPG JPEG WEBP Xamarin Android MonoAndroid MAUI WASM WebAssembly https://github.com/sungaila/PDFtoImage.git git @@ -84,15 +83,15 @@ - + - - - + + + @@ -101,7 +100,7 @@ - + diff --git a/src/PDFtoImage/PdfiumViewer/NativeMethods.cs b/src/PDFtoImage/PdfiumViewer/NativeMethods.cs index dcbf427e..3ec6d112 100644 --- a/src/PDFtoImage/PdfiumViewer/NativeMethods.cs +++ b/src/PDFtoImage/PdfiumViewer/NativeMethods.cs @@ -6,11 +6,13 @@ namespace PDFtoImage.PdfiumViewer { - internal static partial class NativeMethods - { - static NativeMethods() - { - // Load the platform dependent Pdfium.dll if it exist. + internal static partial class NativeMethods + { + static NativeMethods() + { + string? path = null; + try + { #if NET7_0_OR_GREATER string workingDirectory = Assembly.GetExecutingAssembly().Location; if (string.IsNullOrWhiteSpace(workingDirectory)) @@ -24,18 +26,22 @@ static NativeMethods() if (string.IsNullOrWhiteSpace(workingDirectory)) workingDirectory = AppContext.BaseDirectory; #else - var workingDirectory = Assembly.GetExecutingAssembly().GetName(false).CodeBase; - if (string.IsNullOrWhiteSpace(workingDirectory)) - workingDirectory = Process.GetCurrentProcess().MainModule!.FileName!; - if (string.IsNullOrWhiteSpace(workingDirectory)) - workingDirectory = AppContext.BaseDirectory; + var workingDirectory = Assembly.GetExecutingAssembly().GetName(false).CodeBase; + if (string.IsNullOrWhiteSpace(workingDirectory)) + workingDirectory = Process.GetCurrentProcess().MainModule!.FileName!; + if (string.IsNullOrWhiteSpace(workingDirectory)) + workingDirectory = AppContext.BaseDirectory; #endif - LoadNativeLibrary(Path.GetDirectoryName(new Uri(workingDirectory).LocalPath)!); - } + path = Path.GetDirectoryName(new Uri(workingDirectory).LocalPath); + } + catch (Exception) { } - private static void LoadNativeLibrary(string path) - { + LoadNativeLibrary(path); + } + + private static void LoadNativeLibrary(string? path = null) + { #if ANDROID || MONOANDROID LoadNativeLibraryAndroid(); #elif NET6_0_OR_GREATER @@ -45,7 +51,7 @@ private static void LoadNativeLibrary(string path) #else throw new PlatformNotSupportedException("Unkown framework and/or platform."); #endif - } + } #if ANDROID || MONOANDROID private static void LoadNativeLibraryAndroid() @@ -64,7 +70,7 @@ private static void LoadNativeLibraryAndroid() Java.Lang.JavaSystem.LoadLibrary("pdfium"); } #elif NET6_0_OR_GREATER - private static void LoadNativeLibraryNetCore(string path) + private static void LoadNativeLibraryNetCore(string? path) { if (path == null) return; @@ -104,7 +110,19 @@ private static void LoadNativeLibraryNetCore(string path) }; pdfiumLibName = "libpdfium.dylib"; } - else + else if (OperatingSystem.IsMacCatalyst()) + { + throw new NotSupportedException("Mac Catalyst is not supported."); + } + else if (OperatingSystem.IsIOS()) + { + throw new NotSupportedException("iOS and Mac Catalyst are not supported."); + } + else if (OperatingSystem.IsTvOS()) + { + throw new NotSupportedException("tvOS is not supported."); + } + else { throw new NotSupportedException("Only win-x86, win-x64, win-arm64, linux-x64, linux-arm, linux-arm64, osx-x64, and osx-arm64 are supported."); } @@ -143,7 +161,7 @@ private static IntPtr ImportResolver(string libraryName, Assembly assembly, DllI return IntPtr.Zero; } #elif NETFRAMEWORK - private static void LoadNativeLibraryNetFX(string path) + private static void LoadNativeLibraryNetFX(string? path) { if (path == null) return; @@ -185,5 +203,5 @@ private static void LoadNativeLibraryNetFX(string path) [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] private static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPWStr)] string lpLibFileName); #endif - } + } } diff --git a/src/WebConverter/WebConverter.csproj b/src/WebConverter/WebConverter.csproj index 040684bf..f1aa840a 100644 --- a/src/WebConverter/WebConverter.csproj +++ b/src/WebConverter/WebConverter.csproj @@ -7,7 +7,7 @@ PDFtoImage.WebConverter PDFtoImage.WebConverter PDFtoImage.WebConverter.Program - 2.4.1 + 2.4.2 true true true @@ -34,8 +34,8 @@ - - + + From 7f4011bdf71f061865e1ef844bda9874144cf748 Mon Sep 17 00:00:00 2001 From: David Sungaila Date: Wed, 11 Oct 2023 14:36:21 +0200 Subject: [PATCH 2/2] Fix indentation --- src/PDFtoImage/PdfiumViewer/NativeMethods.cs | 162 +++++++++---------- 1 file changed, 81 insertions(+), 81 deletions(-) diff --git a/src/PDFtoImage/PdfiumViewer/NativeMethods.cs b/src/PDFtoImage/PdfiumViewer/NativeMethods.cs index 3ec6d112..ce1ff557 100644 --- a/src/PDFtoImage/PdfiumViewer/NativeMethods.cs +++ b/src/PDFtoImage/PdfiumViewer/NativeMethods.cs @@ -14,17 +14,17 @@ static NativeMethods() try { #if NET7_0_OR_GREATER - string workingDirectory = Assembly.GetExecutingAssembly().Location; - if (string.IsNullOrWhiteSpace(workingDirectory)) - workingDirectory = Environment.ProcessPath!; - if (string.IsNullOrWhiteSpace(workingDirectory)) - workingDirectory = AppContext.BaseDirectory; + string workingDirectory = Assembly.GetExecutingAssembly().Location; + if (string.IsNullOrWhiteSpace(workingDirectory)) + workingDirectory = Environment.ProcessPath!; + if (string.IsNullOrWhiteSpace(workingDirectory)) + workingDirectory = AppContext.BaseDirectory; #elif NET6_0_OR_GREATER - var workingDirectory = Assembly.GetExecutingAssembly().GetName(false).CodeBase; - if (string.IsNullOrWhiteSpace(workingDirectory)) - workingDirectory = Environment.ProcessPath!; - if (string.IsNullOrWhiteSpace(workingDirectory)) - workingDirectory = AppContext.BaseDirectory; + var workingDirectory = Assembly.GetExecutingAssembly().GetName(false).CodeBase; + if (string.IsNullOrWhiteSpace(workingDirectory)) + workingDirectory = Environment.ProcessPath!; + if (string.IsNullOrWhiteSpace(workingDirectory)) + workingDirectory = AppContext.BaseDirectory; #else var workingDirectory = Assembly.GetExecutingAssembly().GetName(false).CodeBase; if (string.IsNullOrWhiteSpace(workingDirectory)) @@ -45,7 +45,7 @@ private static void LoadNativeLibrary(string? path = null) #if ANDROID || MONOANDROID LoadNativeLibraryAndroid(); #elif NET6_0_OR_GREATER - LoadNativeLibraryNetCore(path); + LoadNativeLibraryNetCore(path); #elif NETFRAMEWORK LoadNativeLibraryNetFX(path); #else @@ -70,46 +70,46 @@ private static void LoadNativeLibraryAndroid() Java.Lang.JavaSystem.LoadLibrary("pdfium"); } #elif NET6_0_OR_GREATER - private static void LoadNativeLibraryNetCore(string? path) - { - if (path == null) - return; - - string runtimeIdentifier; - string pdfiumLibName; - - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - runtimeIdentifier = RuntimeInformation.ProcessArchitecture switch - { - Architecture.X86 => "win-x86", - Architecture.X64 => "win-x64", - Architecture.Arm64 => "win-arm64", - _ => throw new PlatformNotSupportedException("Only x86-64, x86 and arm64 are supported on Windows.") - }; - pdfiumLibName = "pdfium.dll"; - } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) - { - runtimeIdentifier = RuntimeInformation.ProcessArchitecture switch - { - Architecture.X64 => "linux-x64", - Architecture.Arm => "linux-arm", - Architecture.Arm64 => "linux-arm64", - _ => throw new PlatformNotSupportedException("Only x86-64, arm and arm64 are supported on Linux.") - }; - pdfiumLibName = "libpdfium.so"; - } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - { - runtimeIdentifier = RuntimeInformation.ProcessArchitecture switch - { - Architecture.X64 => "osx-x64", - Architecture.Arm64 => "osx-arm64", - _ => throw new PlatformNotSupportedException("Only x86-64 and arm64 are supported on macOS.") - }; - pdfiumLibName = "libpdfium.dylib"; - } + private static void LoadNativeLibraryNetCore(string? path) + { + if (path == null) + return; + + string runtimeIdentifier; + string pdfiumLibName; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + runtimeIdentifier = RuntimeInformation.ProcessArchitecture switch + { + Architecture.X86 => "win-x86", + Architecture.X64 => "win-x64", + Architecture.Arm64 => "win-arm64", + _ => throw new PlatformNotSupportedException("Only x86-64, x86 and arm64 are supported on Windows.") + }; + pdfiumLibName = "pdfium.dll"; + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + runtimeIdentifier = RuntimeInformation.ProcessArchitecture switch + { + Architecture.X64 => "linux-x64", + Architecture.Arm => "linux-arm", + Architecture.Arm64 => "linux-arm64", + _ => throw new PlatformNotSupportedException("Only x86-64, arm and arm64 are supported on Linux.") + }; + pdfiumLibName = "libpdfium.so"; + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + runtimeIdentifier = RuntimeInformation.ProcessArchitecture switch + { + Architecture.X64 => "osx-x64", + Architecture.Arm64 => "osx-arm64", + _ => throw new PlatformNotSupportedException("Only x86-64 and arm64 are supported on macOS.") + }; + pdfiumLibName = "libpdfium.dylib"; + } else if (OperatingSystem.IsMacCatalyst()) { throw new NotSupportedException("Mac Catalyst is not supported."); @@ -123,43 +123,43 @@ private static void LoadNativeLibraryNetCore(string? path) throw new NotSupportedException("tvOS is not supported."); } else - { - throw new NotSupportedException("Only win-x86, win-x64, win-arm64, linux-x64, linux-arm, linux-arm64, osx-x64, and osx-arm64 are supported."); - } + { + throw new NotSupportedException("Only win-x86, win-x64, win-arm64, linux-x64, linux-arm, linux-arm64, osx-x64, and osx-arm64 are supported."); + } - LoadLibrary(path, runtimeIdentifier, pdfiumLibName); - } + LoadLibrary(path, runtimeIdentifier, pdfiumLibName); + } #endif #if !MONOANDROID && !ANDROID - private static string? _pdfiumLibPath; + private static string? _pdfiumLibPath; #endif #if NET6_0_OR_GREATER && !ANDROID - private static void LoadLibrary(string path, string runtimeIdentifier, string pdfiumLibName) - { - if (File.Exists(Path.Combine(path, pdfiumLibName))) - { - // dotnet publish with a given runtime identifier (not portable) will put PDFium into the root folder - _pdfiumLibPath = Path.Combine(path, pdfiumLibName); - } - else - { - // in any other case there should be a runtimes folder - _pdfiumLibPath = Path.Combine(path, "runtimes", runtimeIdentifier, "native", pdfiumLibName); - } - - NativeLibrary.SetDllImportResolver(typeof(NativeMethods).Assembly, ImportResolver); - NativeLibrary.Load(_pdfiumLibPath, Assembly.GetExecutingAssembly(), default); - } - - private static IntPtr ImportResolver(string libraryName, Assembly assembly, DllImportSearchPath? searchPath) - { - if (_pdfiumLibPath != null && libraryName != null && libraryName.Contains("pdfium")) - return NativeLibrary.Load(_pdfiumLibPath, assembly, searchPath); - - return IntPtr.Zero; - } + private static void LoadLibrary(string path, string runtimeIdentifier, string pdfiumLibName) + { + if (File.Exists(Path.Combine(path, pdfiumLibName))) + { + // dotnet publish with a given runtime identifier (not portable) will put PDFium into the root folder + _pdfiumLibPath = Path.Combine(path, pdfiumLibName); + } + else + { + // in any other case there should be a runtimes folder + _pdfiumLibPath = Path.Combine(path, "runtimes", runtimeIdentifier, "native", pdfiumLibName); + } + + NativeLibrary.SetDllImportResolver(typeof(NativeMethods).Assembly, ImportResolver); + NativeLibrary.Load(_pdfiumLibPath, Assembly.GetExecutingAssembly(), default); + } + + private static IntPtr ImportResolver(string libraryName, Assembly assembly, DllImportSearchPath? searchPath) + { + if (_pdfiumLibPath != null && libraryName != null && libraryName.Contains("pdfium")) + return NativeLibrary.Load(_pdfiumLibPath, assembly, searchPath); + + return IntPtr.Zero; + } #elif NETFRAMEWORK private static void LoadNativeLibraryNetFX(string? path) {