DinkToPdf: Unable to load DLL 'libwkhtmltox': The specified module could not be found. When using Nuget package

When using the DinkToPdf Nuget package I get the error message below because it is looking for the libwkhtmltox DLL in the same folder the Nuget package DLL is in. For me using VS 2017 on Windows 10 this is:

%UserProfile%\.nuget\packages\dinktopdf\1.0.8\lib\netstandard1.6

When I either manually copy the correct libwkhtmltox DLL to this folder or include the source of the DinkToPdf project into my solution I no longer get this error. By including the project source into my solution the DinkToPdf DLL is then compiled into my output folder where it then also successfully finds the libwkhtmltox DLL.

Is it possible to resolve this issue without having to use the project source or regsvr32.exe? I see that TuesPechkin has an IDeployment interface to address this issue (see: https://github.com/tuespetre/TuesPechkin/issues/57). Is it possible to do something similar in DinkToPdf?

System.AggregateException: One or more errors occurred. (Unable to load DLL 'libwkhtmltox': The specified module could not be found. (Exception from HRESULT: 0x8007007E)) ---> System.DllNotFoundException: Unable to load DLL 'libwkhtmltox': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
   at DinkToPdf.WkHtmlToXBindings.wkhtmltopdf_init(Int32 useGraphics)
   at DinkToPdf.PdfTools.Load() in C:\Users\admin\Documents\DinkToPdf\src\DinkToPdf\PdfTools.cs:line 27
   at DinkToPdf.BasicConverter.Convert(IDocument document) in C:\Users\admin\Documents\DinkToPdf\src\DinkToPdf\BasicConverter.cs:line 42
   at DinkToPdf.SynchronizedConverter.<>n__0(IDocument document)
   at DinkToPdf.SynchronizedConverter.<>c__DisplayClass5_0.<Convert>b__0() in C:\Users\admin\Documents\DinkToPdf\src\DinkToPdf\SynchronizedConverter.cs:line 27
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()
   --- End of inner exception stack trace ---
   at DinkToPdf.SynchronizedConverter.Invoke[TResult](Func`1 delegate) in C:\Users\admin\Documents\DinkToPdf\src\DinkToPdf\SynchronizedConverter.cs:line 51
   at DinkToPdf.SynchronizedConverter.Convert(IDocument document) in C:\Users\admin\Documents\DinkToPdf\src\DinkToPdf\SynchronizedConverter.cs:line 27

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 91 (18 by maintainers)

Most upvoted comments

Can you please add this class into your project just to test it before i put in the library?

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

Create and call CustomAssemblyLoadContext before you create your converter:

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

var converter = new SynchronizedConverter(new PdfTools());

Tested on Windows 10 64bit and Ubuntu LTS 16.04 64bit.

Will this work for your use case?

I was getting similar unable to load dll issues as above. I had no issues after switching to this fork: https://www.nuget.org/packages/RndUsr0.DinkToPdf/. I found it linked from this discussion: https://github.com/rdvojmoc/DinkToPdf/pull/18.

Hopefully this saves someone time from trying the myriad solutions listed in this thread.

frustrating to read through all the comments with no resolution - there’s obviously an issue with core 2 loading external dll’s

I added the DinkToPdf assembly (1.0.8) in my asp net core 2 API project.

In the Startup.cs, method ConfigureServices, I loaded the libwkhtmltox assembly.

public void ConfigureServices(IServiceCollection services)
        {
...

var architectureFolder = (IntPtr.Size == 8) ? "64 bit" : "32 bit";
            var wkHtmlToPdfPath = Path.Combine(_hostingEnvironment.ContentRootPath, $"wkhtmltox\\v0.12.4\\{architectureFolder}\\libwkhtmltox");

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

            // Add converter to DI
            services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));

...
}

I added this class inside my 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();
        }
    }

On my controller.

[HttpGet]
        public async Task<IActionResult> PrintAsync()
        {
            var vm = new { teste = "" };

            string documentContent = await _templateService.RenderTemplateAsync("RelatorioAuditoria", vm);

            var doc = new HtmlToPdfDocument()
            {
                GlobalSettings = {
                    PaperSize = PaperKind.A3,
                    Orientation = Orientation.Landscape,
                },

                Objects = {
                    new ObjectSettings()
                    {
                        HtmlContent = documentContent
                    }
                }
            };

            byte[] pdf = _converter.Convert(doc);

            return new FileContentResult(pdf, "application/pdf");
        }

It worked perfectly, I can reread my ReportAuditoria.cshtml and then convert it to pdf.

@panache62 I am using this with dotnetcore 2. I feel the readme could be improved a lot, there is no mention that https://wkhtmltopdf.org/downloads.html this is required to be installed on the server. Also direct injection is mandatory otherwise the dll has memory issues when it is re upped.

FYI I tried using this work around to copy the nuget references to the output folder:

<PropertyGroup>
    <TargetFramework>netcoreapp1.1</TargetFramework>
    <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
  </PropertyGroup>

Source here: https://stackoverflow.com/questions/43837638/how-to-get-net-core-projects-to-copy-nuget-references-to-build-output.

This copies the referenced nuget binaries to the output folder but the .net core web app still uses the dinktopdf.dll located in:

%UserProfile%\.nuget\packages\dinktopdf\1.0.8\lib\netstandard1.6

So unfortunately this doesn’t work

issue was resolved after installing MS visual C++ 2015 redistributable package in the server. Thanks a lot for the support

Recently I faced the same problem. Maybe this is a really stupid question, but is there any reason why the libwkhtmltox dll and other binaries are not packaged together in the DinkToPdf nuget package?

download this on server, where you try to use libwkhtmltox.dll https://support.microsoft.com/ru-ru/help/2977003/the-latest-supported-visual-c-downloads

On Linux, this can help:

curl -o /usr/lib/libwkhtmltox.so \
        --location \
        https://github.com/rdvojmoc/DinkToPdf/raw/v1.0.8/v0.12.4/64%20bit/libwkhtmltox.so

Can you please run command apt-get update and then apt-get install libgdiplus inside docker image?

arjasepp Azure by default requires the 32 bit version. Check your Application Settings under the App Service your deploying to. See also https://serverfault.com/questions/567987/32bits-or-64bits-for-windows-azure-web-sites.

Unless you’re running Windows XP locally your Dev environment will require the 64 bit version which for me created quite a problem when it came to getting our solution to build correctly for Dev and also for our Azure Test and UAT environments.

Because we are using a build server operating on a 64 bit OS I had to add the following to the csproj using DinkToPdf and therefore also using the WkHtmlToPdf library.

  <ItemGroup Condition=" '$(CONFIGURATION)' == 'Debug' And '$(PROCESSOR_ARCHITECTURE)' == 'x86' And '$(PROCESSOR_ARCHITEW6432)' == '' ">
    <ContentWithTargetPath Include="..\..\lib\wkhtmltox\32 bit\libwkhtmltox.dll">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <TargetPath>libwkhtmltox.dll</TargetPath>
    </ContentWithTargetPath>
  </ItemGroup>

  <ItemGroup Condition=" '$(CONFIGURATION)' == 'Debug' And '$(PROCESSOR_ARCHITECTURE)' == 'AMD64' Or '$(PROCESSOR_ARCHITEW6432)' == 'AMD64' ">
    <ContentWithTargetPath Include="..\..\lib\wkhtmltox\64 bit\libwkhtmltox.dll">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <TargetPath>libwkhtmltox.dll</TargetPath>
    </ContentWithTargetPath>
  </ItemGroup>

  <ItemGroup Condition=" '$(CONFIGURATION)' == 'Release' ">
    <ContentWithTargetPath Include="..\..\lib\wkhtmltox\32 bit\libwkhtmltox.dll">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <TargetPath>libwkhtmltox.dll</TargetPath>
    </ContentWithTargetPath>
  </ItemGroup>

I added the WkHtmlToPdf binaries in a “lib\wkhtmltox” folder at the solution level hence the "…" parent folder traversing at the project level.

Thanks!

And yes this works in my case.

I have followed timfisher’s comments as above but still am unable to load the dll. I am using Visual Studio 2017 Net Core 2.0on a Windows 10 PC. It works fine using the localhost IIS express web server, however, when I publish to the IIS 10 server, it cannot find the ‘libwkhtmltox’.dll. I have verified that the files have been copied correctly, and have even tried manual placing of the dll file in every conceivable location.

I guess first up, two questions need answering:

  1. Does it work with Net Core 2.0?
  2. Does it work on IIS 10 (Windows Server 2016)

Could some one please help me here.

Many thanks in advance

By changing to release mode from debug in visual studio, i can successfully convert html to pdf using dinktopdf in .net core microservice. still don’t understand why debug build won’t work though

You can download libwkhtmlox.dll here

This is Dockerfile with microsoft/aspnetcore-build:1.0-1.1 image as parent:

FROM microsoft/aspnetcore-build:1.0-1.1

RUN ["apt-get", "update"]
RUN ["apt-get", "-y", "install", "libgdiplus"]

WORKDIR /app

COPY / .

ENTRYPOINT ["dotnet", "DinkToPfd.TestConsoleApp.dll"]

I published DinkToPfd.TestConsoleApp, copied libwkhtmltox.so and libwkhtmltox.dll (they are not published by default) to a publish folder and created docker from it with command sudo docker build -t dinktopdf and then run it with sudo docker run -t dinktopdf

Everything worked as expected.

Hello,

If you are using Ubuntu based docker please install libgdiplus. sudo apt-get install libgdiplus

See issue #3 .