Skip to content

Commit

Permalink
Loading pdfium lib for publish scenarios fixed
Browse files Browse the repository at this point in the history
  • Loading branch information
sungaila committed Aug 26, 2021
1 parent 54f57c8 commit 1b40ad1
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 28 deletions.
2 changes: 1 addition & 1 deletion src/Console/Console.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<AssemblyName>PDFtoImage.Console</AssemblyName>
<RootNamespace>PDFtoImage.Console</RootNamespace>
<StartupObject>PDFtoImage.Console.Program</StartupObject>
<Version>1.1.2</Version>
<Version>1.1.3</Version>
</PropertyGroup>

<!-- C# compiler -->
Expand Down
4 changes: 2 additions & 2 deletions src/PDFtoImage/PDFtoImage.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

<!-- NuGet -->
<PropertyGroup>
<VersionPrefix>1.1.2</VersionPrefix>
<VersionPrefix>1.1.3</VersionPrefix>
<VersionSuffix></VersionSuffix>
<Authors>David Sungaila</Authors>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
Expand All @@ -21,7 +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 pdfium.dll loading for shadow copies.</PackageReleaseNotes>
<PackageReleaseNotes>Fixed pdfium.dll loading for published projects with RuntimeIdentifier.</PackageReleaseNotes>
<PackageTags>PDF Bitmap Image Convert Conversion C# PDFium</PackageTags>
<RepositoryUrl>https://github.com/sungaila/PDFtoImage.git</RepositoryUrl>
<RepositoryType>git</RepositoryType>
Expand Down
69 changes: 44 additions & 25 deletions src/PDFtoImage/PdfiumViewer/NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,60 +15,67 @@ static NativeMethods()

private static string? _pdfiumLibPath;

private static bool LoadNativeLibrary(string path)
private static void LoadNativeLibrary(string path)
{
if (path == null)
return false;

_pdfiumLibPath = Path.Combine(path, "runtimes");
return;

#if NETCOREAPP3_0_OR_GREATER
string runtimeIdentifier;
string pdfiumLibName;

if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
_pdfiumLibPath = Path.Combine(_pdfiumLibPath, RuntimeInformation.ProcessArchitecture switch
runtimeIdentifier = RuntimeInformation.ProcessArchitecture switch
{
Architecture.X86 => "win-x86",
Architecture.X64 => "win-x64",
_ => throw new PlatformNotSupportedException("Only x86-64 and x86 are supported on Windows.")
});
_pdfiumLibPath = Path.Combine(_pdfiumLibPath, "native");
_pdfiumLibPath = Path.Combine(_pdfiumLibPath, "pdfium.dll");
};
pdfiumLibName = "pdfium.dll";
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
_pdfiumLibPath = Path.Combine(_pdfiumLibPath, RuntimeInformation.ProcessArchitecture switch
runtimeIdentifier = RuntimeInformation.ProcessArchitecture switch
{
Architecture.X64 => "linux-x64",
_ => throw new PlatformNotSupportedException("Only x86-64 is supported on Linux.")
});
_pdfiumLibPath = Path.Combine(_pdfiumLibPath, "native");
_pdfiumLibPath = Path.Combine(_pdfiumLibPath, "libpdfium.so");
};
pdfiumLibName = "libpdfium.so";
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
_pdfiumLibPath = Path.Combine(_pdfiumLibPath, RuntimeInformation.ProcessArchitecture switch
runtimeIdentifier = RuntimeInformation.ProcessArchitecture switch
{
Architecture.X64 => "osx-x64",
Architecture.Arm64 => "osx-arm64",
_ => throw new PlatformNotSupportedException("Only x86-64 and arm64 are supported on macOS.")
});
_pdfiumLibPath = Path.Combine(_pdfiumLibPath, "native");
_pdfiumLibPath = Path.Combine(_pdfiumLibPath, "libpdfium.dylib");
};
pdfiumLibName = "libpdfium.dylib";
}
else
{
throw new NotSupportedException("Only win-x86, win-x64, linux-x64, osx-x64 and osx-arm64 are supported.");
}
}

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);

return File.Exists(_pdfiumLibPath) && NativeLibrary.Load(_pdfiumLibPath, Assembly.GetExecutingAssembly(), default) != IntPtr.Zero;
NativeLibrary.Load(_pdfiumLibPath, Assembly.GetExecutingAssembly(), default);
#else
_pdfiumLibPath = Path.Combine(_pdfiumLibPath, Environment.Is64BitProcess ? "win-x64" : "win-x86");
_pdfiumLibPath = Path.Combine(_pdfiumLibPath, "native");
_pdfiumLibPath = Path.Combine(_pdfiumLibPath, "pdfium.dll");
_pdfiumLibPath = Path.Combine(path, "runtimes", Environment.Is64BitProcess ? "win-x64" : "win-x86", "native", "pdfium.dll");

return File.Exists(_pdfiumLibPath) && LoadLibrary(_pdfiumLibPath) != IntPtr.Zero;
LoadLibrary(_pdfiumLibPath);
#endif
}

Expand All @@ -81,8 +88,20 @@ private static IntPtr ImportResolver(string libraryName, Assembly assembly, DllI
return NativeLibrary.Load(_pdfiumLibPath, assembly, searchPath);
}
#else
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Auto)]
private static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPWStr)] string lpFileName);
/// <summary>Loads the specified module into the address space of the calling process.</summary>
/// <param name="lpLibFileName">
/// <para>The name of the module. This can be either a library module (a .dll file) or an executable module (an .exe file). The name specified is the file name of the module and is not related to the name stored in the library module itself, as specified by the <b>LIBRARY</b> keyword in the module-definition (.def) file. If the string specifies a full path, the function searches only that path for the module. If the string specifies a relative path or a module name without a path, the function uses a standard search strategy to find the module; for more information, see the Remarks. If the function cannot find the module, the function fails. When specifying a path, be sure to use backslashes (\\), not forward slashes (/). For more information about paths, see <a href="https://docs.microsoft.com/windows/desktop/FileIO/naming-a-file">Naming a File or Directory</a>. If the string specifies a module name without a path and the file name extension is omitted, the function appends the default library extension .dll to the module name. To prevent the function from appending .dll to the module name, include a trailing point character (.) in the module name string.</para>
/// <para><see href="https://docs.microsoft.com/windows/win32/api//libloaderapi/nf-libloaderapi-loadlibraryw#parameters">Read more on docs.microsoft.com</see>.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is a handle to the module. If the function fails, the return value is NULL. To get extended error information, call <a href="/windows/desktop/api/errhandlingapi/nf-errhandlingapi-getlasterror">GetLastError</a>.</para>
/// </returns>
/// <remarks>
/// <para><see href="https://docs.microsoft.com/windows/win32/api//libloaderapi/nf-libloaderapi-loadlibraryw">Learn more about this API from docs.microsoft.com.</see></para>
/// </remarks>
[DllImport("Kernel32", ExactSpelling = true, EntryPoint = "LoadLibraryW", SetLastError = true)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
private static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPWStr)] string lpLibFileName);
#endif
}
}
}

0 comments on commit 1b40ad1

Please sign in to comment.