HakanL / WkHtmlToPdf-DotNet

C# .NET Core wrapper for wkhtmltopdf library that uses Webkit engine to convert HTML pages to PDF.
GNU Lesser General Public License v3.0
366 stars 66 forks source link

Unable to load native library - Windows 10/11 #117

Closed pamar1908 closed 10 months ago

pamar1908 commented 10 months ago

I am reopening an older issue for which I didn't find any actual solutions. Publishing a .Net Framework (4.8) is not copying the required libraries to output. The following error is raised on Windows 10/11:

"Unable to load native library. The platform may be missing native dependencies (libjpeg62, etc)"

Is there any actual solution to this problem or at least an easy to implement workaround?

HakanL commented 10 months ago

The primary focus has been on .NET Core, but I believe it's possible to solve for FW as well. The issue is probably that the native library is either not deployed in the correct folder, or .NET FW doesn't find it. You need to troubleshoot the deployed solution to see if the files are there and go from there. I believe in the past there's been issues getting the Nuget packages for work for both FW and Core, you may have to manually copy the library in your solution to the destination folder.

pamar1908 commented 10 months ago

Thank you for your reply. Since I am not an expert in deployment, can I ask which libraries? There is a folder called runtimes in bin Debug/Release which seems to include some wkhtmltopdf libraries. I have tried copying the folder from bin to publish with no luck though.

HakanL commented 10 months ago

The native library is the runtimes\win-x64\native\wkhtmltox.dll (or x86 depending on your bitness). I believe it should go into the runtimes/native/win-x64 folder, but that's where you need to do some research and trial and error.

pamar1908 commented 10 months ago

That's where I have them. Is there any conflict with the .deploy extensions of the rest of the files? Is there any reference to these libraries that needs to be added in some app configuration file? (sorry but as I said I don't have experience in deployment)

HakanL commented 10 months ago

Shouldn't be a conflict, .NET will just search some specific folders for a DLL and ignore the rest. But I don't know exactly where, it takes some trial and error and some research, maybe by looking at the issues here, I think someone has had a similar issue. Calling a native library is complex, but unfortunately there's no good alternative when it comes to HTML to PDF generation.

HakanL commented 10 months ago

I just realized we have a .NET Framework example in here, is that working?

pamar1908 commented 10 months ago

Which example? I copied the runtimes from a .Net Core publish and nothing works. I don't know if there is a possible solution.

HakanL commented 10 months ago

This project: https://github.com/HakanL/WkHtmlToPdf-DotNet/tree/master/src/PlatformNuGetTests/NetFramework48

pamar1908 commented 10 months ago

Nope, same issue.

HakanL commented 10 months ago

I just tested the project NetFramework48 and it worked fine. I think it may be something with your system, maybe try to run the native wkhtmltopdf project and go from there?

pamar1908 commented 10 months ago

Just to clarify the problem for me occurs when publishing the app as clickonce application. It does not create a runtimes folder. If I manually copy the runtimes folder it works fine if I run the EXE from the publish folder, but fails if I run the .application manifest to properly run as a clickonce application.

When you say the test project worked, did publishing create a runtimes folders appropriately? (Also, if I upgrade the app to .NET 6 then publishing works as expected. However, this is not an option for now as the upgrade is not a one-click process and it messes up other aspects of my application.)

I assume it requires the library for the conversation. Is there a possibility to provide the option to specify the path of the native library? In that case we could create a shared "runtimes" folder.

HakanL commented 10 months ago

I see, publishing can be tricky in .NET FW. I recall someone reporting they had to add some extra commands to the csproj. If you search this project maybe you'll find it. Then ClickOnce adds its own set of complexity. I didn't test to publish, only ran it. You can't specify the path to the native library because it's the .NET runtime that is responsible for loading it, can't be controlled by the managed code, unfortunately.

pamar1908 commented 10 months ago

Ok I managed to find a workaround based on suggestions from previous comments:

I added the runtimes folder in the project and set to "Copy always" for the two runtime libraries.

As I am not experienced in deployment, can you guide me to understand the following: I understand that wkhtmltox is a runtime dependency. But where in my project this dependency is specified. There is no mention of it in any property and when compiling the library is copied to the output folder. I am trying to understand how there is no way to control this dependency to force it to be copied to the output folder without manual workaround like what I ended up doing. Also, where is this wkhtmltox library is found/saved when compiling to copy it to the output folder?

HakanL commented 10 months ago

Deployment is an art in itself, I don't think I'll be able to give you much additional information. The native library binary is added to this project/Nuget package and the build process will copy it to the standard location where .NET expect native libraries to be found. It probably helps to read up a little on how .NET handles native dependencies. If I remember correctly the publish for .NET Framework and .NET Core is different, so it may be that further tweaks are required in this wrapper project to successfully publish without workarounds. But since most users have moved on to .NET Core you'll find less and less people to spend time fixing .NET FW issues. We accept PRs though, as long as it doesn't break the support for .NET Core.

pamar1908 commented 10 months ago

I see. Thank you very much for all the help.

CollinMonahanTekGs commented 6 months ago

I got the same error trying to run on Windows 10 in .Net Core 6,

2024-03-13T21:33:21.702Z        1455677f-4d44-407a-b455-66ab88867ec6    info    {"method_name":"HandleRequest","source_file_path":"C:\\Users\\xxxxxxxxxxxxxxx\\src\\Handlers\\BaseHandler.cs","source_line_number":68,"message":"System.Func`1[System.String]Unable to load native library. The platform may be missing native dependencies (libjpeg62, etc). Or the current platform is not supported. ","service":"xxxxxxx","stack_trace":"   
at WkHtmlToPdfDotNet.ModuleFactory.GetModule()\n   at WkHtmlToPdfDotNet.PdfTools.Load()\n   at WkHtmlToPdfDotNet.BasicConverter.Convert(IDocument document)\n

But I believe with this project it's trying to run from inside a Linux Docker image, to simulate cloud deployment.

Update, I see the example now, the Dockerfile has a lot of added libs, that is likely missing in this case.