I am using DinkToPDF library to convert a html string to it's equivalent PDF. To use this library we have to import a native library provided which is libwkhtmltox.dll. This works fine when I run my .net core project locally,however when I try to publish my web project as an App Service in Azure, I get the following error,
Unhandled Exception: System.DllNotFoundException: Unable to load shared library '/home/site/wwwroot/libwkhtmltox.dll' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: /home/site/wwwroot/libwkhtmltox.dll: cannot open shared object file: No such file or directory
I have referred the library usage in the startup.cs file as below.
internal class CustomAssemblyLoadContext : AssemblyLoadContext
{
public IntPtr LoadUnmanagedLibrary(string absolutePath)
{
return LoadUnmanagedDll(absolutePath);
}
protected override IntPtr LoadUnmanagedDll(String unmanagedDllName)
{
return LoadUnmanagedDllFromPath(unmanagedDllName);
}
protected override Assembly Load(AssemblyName assemblyName)
{
throw new NotImplementedException();
}
}
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));
var context = new CustomAssemblyLoadContext();
context.LoadUnmanagedLibrary(Path.Combine(Directory.GetCurrentDirectory(), "libwkhtmltox.dll"));
.
.
.
}
Please help me find out the solution for this error.
you need set the absotule path for the library, and for windows it is not necessary use ".dll", in my case it is placed in [project_root]/wkhtmltox/v0.12.4/[x_64|x_86]
var architectureFolder = (IntPtr.Size == 8) ? "x_64" : "x_86";
var wkHtmlToPdfFileName = "libwkhtmltox";
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
wkHtmlToPdfFileName += ".so";
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
wkHtmlToPdfFileName += ".dylib";
}
var wkHtmlToPdfPath = Path.Combine(
new string[] {
_hostingEnvironment.ContentRootPath,
"wkhtmltox",
"v0.12.4",
architectureFolder,
wkHtmlToPdfFileName
});
CustomAssemblyLoadContext context = new CustomAssemblyLoadContext();
context.LoadUnmanagedLibrary(wkHtmlToPdfPath);
services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));
You have to copy the dll extension to the root of your project
After that you have to create an internal class to load the dll
Add this to your class
using System.Runtime.Loader;
using System.Reflection;
the methods to include:
internal class CustomAssemblyLoadContext : AssemblyLoadContext
{
public IntPtr LoadUnmanagedLibrary(string absolutePath)
{
return LoadUnmanagedDll(absolutePath);
}
protected override IntPtr LoadUnmanagedDll(string unmanagedDllName)
{
return LoadUnmanagedDllFromPath(unmanagedDllName);
}
protected override Assembly Load(AssemblyName assemblyName)
{
throw new NotImplementedException();
}
}
In dockerfile insert the following commands to the componente engine html to pdf:
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
RUN apt-get update
RUN apt-get install -y apt-utils
RUN apt-get install -y libgdiplus
RUN apt-get install -y libc6-dev
RUN ln -s /usr/lib/libgdiplus.so/usr/lib/gdiplus.dll
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With