在 Azure 中发布为应用服务后,使用 DinkToPDF 进行 PDF 转换时无法加载外部库"libwkhtmltox.dll"



我正在使用DinkToPDF库将html字符串转换为等效的PDF。要使用此库,我们必须导入提供的本机库libwkhtmltox.dll。当我在本地运行 .net 核心项目时,这工作正常,但是当我尝试将我的 Web 项目发布为 Azure 中的应用服务时,出现以下错误,

未处理的异常:System.DllNotFoundException:无法加载共享库"/home/site/wwwroot/libwkhtmltox.dll"或其依赖项之一。为了帮助诊断加载问题,请考虑设置LD_DEBUG环境变量:/home/site/wwwroot/libwkhtmltox.dll:无法打开共享对象文件:没有这样的文件或目录

我已经在startup.cs文件中引用了库的用法,如下所示。

    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"));
         .
         .
         .
        }

请帮助我找出此错误的解决方案。

在 dockerfile 中,将以下命令插入到组件引擎 html 到 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
您需要

为库设置绝对路径,对于 Windows,没有必要使用".dll",在我的情况下它被放置在[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()));

您必须将 dll 扩展复制到项目的根目录

之后,您必须创建一个内部类来加载 dll

将此添加到您的课程中

using System.Runtime.Loader;
using System.Reflection;

方法包括:

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

试试这个:从 https://github.com/rdvojmoc/DinkToPdf/tree/master/v0.12.4 下载软件包

通过自定义程序集引用将其添加到项目引用中,并在启动项目中注册。这是自定义程序集加载上下文,可以从绝对路径加载库。

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

在 Statup 中.cs添加以下代码。在创建转换器之前调用 CustomAssemblyLoadContext:

CustomAssemblyLoadContext

context = new CustomAssemblyLoadContext((;上下文。加载非托管库(路径(;

var converter = new SyncdConverter(new PdfTools(((;服务业。添加单例(转换器(;服务业。AddSingleton(typeof(IConverter(, new SyncdConverter(new PdfTools((((;

最新更新