Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for Android release builds not loading libpdfium correctly #46

Merged
merged 2 commits into from
Oct 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Console/Console.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<AssemblyName>PDFtoImage.Console</AssemblyName>
<RootNamespace>PDFtoImage.Console</RootNamespace>
<StartupObject>PDFtoImage.Console.Program</StartupObject>
<Version>2.4.1</Version>
<Version>2.4.2</Version>
<Configurations>Debug;Release;ReleaseSigned</Configurations>
</PropertyGroup>

Expand Down
15 changes: 7 additions & 8 deletions src/PDFtoImage/PDFtoImage.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

<!-- NuGet -->
<PropertyGroup>
<VersionPrefix>2.4.1</VersionPrefix>
<VersionPrefix>2.4.2</VersionPrefix>
<VersionSuffix></VersionSuffix>
<Authors>David Sungaila</Authors>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
Expand All @@ -21,8 +21,7 @@
<PackageProjectUrl>https://github.com/sungaila/PDFtoImage</PackageProjectUrl>
<PackageIconUrl>https://raw.githubusercontent.com/sungaila/PDFtoImage/master/etc/Icon_128.png</PackageIconUrl>
<Description>A .NET library to render PDF files into images.</Description>
<PackageReleaseNotes>- Fixed an issue where password protected PDF files could not be opened.
- Added PDF specific Exception classes (e.g. PdfPasswordProtectedException).</PackageReleaseNotes>
<PackageReleaseNotes>- Fixed an issue where Android release builds would fail to load libpdfium.</PackageReleaseNotes>
<PackageTags>PDF Bitmap Image Convert Conversion C# PDFium SkiaSharp Skia PNG JPG JPEG WEBP Xamarin Android MonoAndroid MAUI WASM WebAssembly</PackageTags>
<RepositoryUrl>https://github.com/sungaila/PDFtoImage.git</RepositoryUrl>
<RepositoryType>git</RepositoryType>
Expand Down Expand Up @@ -84,15 +83,15 @@
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)'=='net462' or '$(TargetFramework)'=='net481'">
<PackageReference Include="bblanchon.PDFium.Win32" Version="119.0.6029" PrivateAssets="analyzers" />
<PackageReference Include="bblanchon.PDFium.Win32" Version="120.0.6056" PrivateAssets="analyzers" />
<PackageReference Include="SkiaSharp.NativeAssets.Win32" Version="2.88.6" PrivateAssets="analyzers" />
</ItemGroup>

<!-- .NET packages -->
<ItemGroup Condition="'$(TargetFramework)'=='net6.0' or '$(TargetFramework)'=='net7.0'">
<PackageReference Include="bblanchon.PDFium.Linux" Version="119.0.6029" PrivateAssets="analyzers" />
<PackageReference Include="bblanchon.PDFium.macOS" Version="119.0.6029" PrivateAssets="analyzers" />
<PackageReference Include="bblanchon.PDFium.Win32" Version="119.0.6029" PrivateAssets="analyzers" />
<PackageReference Include="bblanchon.PDFium.Linux" Version="120.0.6056" PrivateAssets="analyzers" />
<PackageReference Include="bblanchon.PDFium.macOS" Version="120.0.6056" PrivateAssets="analyzers" />
<PackageReference Include="bblanchon.PDFium.Win32" Version="120.0.6056" PrivateAssets="analyzers" />
<PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="2.88.6" PrivateAssets="analyzers" />
<PackageReference Include="SkiaSharp.NativeAssets.macOS" Version="2.88.6" PrivateAssets="analyzers" />
<PackageReference Include="SkiaSharp.NativeAssets.Win32" Version="2.88.6" PrivateAssets="analyzers" />
Expand All @@ -101,7 +100,7 @@

<!-- Android packages -->
<ItemGroup Condition="'$(TargetFramework)'=='net7.0-android' or '$(TargetFramework)'=='monoandroid10.0'">
<PackageReference Include="bblanchon.PDFium.Android" Version="119.0.6029" PrivateAssets="analyzers" />
<PackageReference Include="bblanchon.PDFium.Android" Version="120.0.6056" PrivateAssets="analyzers" />
<PackageReference Include="SkiaSharp.NativeAssets.Android" Version="2.88.6" PrivateAssets="analyzers" />
</ItemGroup>

Expand Down
218 changes: 118 additions & 100 deletions src/PDFtoImage/PdfiumViewer/NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,46 +6,52 @@

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))
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))
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) { }

LoadNativeLibrary(path);
}

private static void LoadNativeLibrary(string path)
{
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
throw new PlatformNotSupportedException("Unkown framework and/or platform.");
#endif
}
}

#if ANDROID || MONOANDROID
private static void LoadNativeLibraryAndroid()
Expand All @@ -64,86 +70,98 @@ 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";
}
else
{
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);
}
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.");
}
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.");
}

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)
private static void LoadNativeLibraryNetFX(string? path)
{
if (path == null)
return;
Expand Down Expand Up @@ -185,5 +203,5 @@ private static void LoadNativeLibraryNetFX(string path)
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
private static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPWStr)] string lpLibFileName);
#endif
}
}
}
6 changes: 3 additions & 3 deletions src/WebConverter/WebConverter.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<AssemblyName>PDFtoImage.WebConverter</AssemblyName>
<RootNamespace>PDFtoImage.WebConverter</RootNamespace>
<StartupObject>PDFtoImage.WebConverter.Program</StartupObject>
<Version>2.4.1</Version>
<Version>2.4.2</Version>
<RunAOTCompilation>true</RunAOTCompilation>
<WasmNativeStrip>true</WasmNativeStrip>
<PublishTrimmed>true</PublishTrimmed>
Expand All @@ -34,8 +34,8 @@
<ItemGroup>
<PackageReference Include="ByteSize" Version="2.1.1" />
<PackageReference Include="Markdig.Signed" Version="0.33.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.11" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.11" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.12" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.12" PrivateAssets="all" />
<PackageReference Include="SkiaSharp.NativeAssets.WebAssembly" Version="2.88.6" />
<PackageReference Include="Thinktecture.Blazor.FileHandling" Version="2.0.0" />
<PackageReference Include="Thinktecture.Blazor.WebShare" Version="2.0.0" />
Expand Down
Loading