6

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

未处理的异常: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"));
         .
         .
         .
        }

请帮我找出这个错误的解决方案。

4

4 回答 4

1

您需要为库设置绝对路径,对于 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()));
于 2020-05-07T16:42:21.350 回答
1

您必须将 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();
        }
    }
于 2020-05-19T18:58:46.157 回答
1

在 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
于 2021-04-13T18:19:38.593 回答
0

试试这个:从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 上下文 = 新的 CustomAssemblyLoadContext(); context.LoadUnmanagedLibrary(路径);

var 转换器 = 新 SynchronizedConverter(新 PdfTools()); services.AddSingleton(转换器); services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));

于 2021-12-27T12:47:37.743 回答