Unable to load External library "libwkhtmltox.dll" while using DinkToPDF for PDF conversion after publishing as app service in azure
Asked Answered
G

4

8

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.

Gitt answered 10/6, 2019 at 13:33 Comment(2)
How do you fix this? Can you update?Hedonism
How did you fix? Please updateStace
B
2

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
Bilberry answered 13/4, 2021 at 18:19 Comment(1)
missed space between two command arguments, should be: RUN ln -s /usr/lib/libgdiplus.so /usr/lib/gdiplus.dllGrocer
L
1

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()));
Lashondra answered 7/5, 2020 at 16:42 Comment(0)
E
1

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();
        }
    }
Epicritic answered 19/5, 2020 at 18:58 Comment(0)
S
0

Try this: Download package from https://github.com/rdvojmoc/DinkToPdf/tree/master/v0.12.4

Add it to your project reference by custom Assembly reference & register in your startup project. This is custom assembly load context which can load library from absolute path.

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 Statup.cs add below code. Call CustomAssemblyLoadContext before you create your converter:

CustomAssemblyLoadContext context = new CustomAssemblyLoadContext(); context.LoadUnmanagedLibrary(path);

var converter = new SynchronizedConverter(new PdfTools()); services.AddSingleton(converter); services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));

Staford answered 27/12, 2021 at 12:47 Comment(1)
Hey @sachind, added the above steps with also converter but getting the below issue when it is deployed in linux web app, 'One or more errors occurred. (Unable to load shared library 'libwkhtmltox' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: liblibwkhtmltox: cannot open shared object file: No such file or directory)--- at DinkToPdf.SynchronizedConverter.Invoke[TResult](Func`1 delegate)' In azure windows web app it is working as expected but in azure linux web app getting the above error, Any suggestions?Deboer

© 2022 - 2024 — McMap. All rights reserved.