TuesPechkin icon indicating copy to clipboard operation
TuesPechkin copied to clipboard

System.DllNotFoundException - Unable to load DLL 'wkhtmltox.dll': Access is denied

Open mertmtn opened this issue 5 years ago • 6 comments

I am faced with the problem convert html to pdf using TuesPechkin. I have two applications on IIS and both of the apps have different application pool.

But I got an error from one of these:

Unable to load DLL 'wkhtmltox.dll': Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)) Stack trace Server stack trace: at TuesPechkin.WkhtmltoxBindings.wkhtmltopdf_init(Int32 useGraphics) at TuesPechkin.PdfToolset.Load(IDeployment deployment) at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Object[]& outArgs) at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg) Exception rethrown at [0]: at TuesPechkin.ThreadSafeConverter.Invoke[TResult](FuncShim1 delegate) at Codaxy.WkHtmlToPdf.PdfConvert.ConvertHtmlToPdf(List1 documentlist) at ArastirmaYonetim.Controllers.RaporController.HtmlRaporOnizle(ArastirmaRaporAramaKriter raporAramaKriter)

But other app works correctly.

I checked that wkhtmltopdf file of both applications have right permission which is full control.

System web part of web config and I use .net framework 4.7.2

<system.web> <globalization uiCulture="tr" culture="tr-TR" /> <compilation debug="true" targetFramework="4.7.2" > <httpRuntime maxRequestLength="2147483647" executionTimeout="3600" /> <httpModules> </httpModules> </system.web>

mertmtn avatar Feb 12 '20 19:02 mertmtn

Also does it matter that Identity of application pool? I used application pool identity that set both of them.

mertmtn avatar Feb 12 '20 19:02 mertmtn

Did you ever figure this out @mertmtn? I am having the same issue

tofer avatar Apr 15 '21 00:04 tofer

@tofer When I tried to change application pool identity on IIS, it works. I do not remember that what I selected identity. It can be related to your server. You must try to change identity

mertmtn avatar Apr 18 '21 18:04 mertmtn

Thanks @mertmtn for the reply.

I actually found the reason for the issue (as I was having it), which is this line in the TempFolderDeployment class.

It uses the application's base directory name AppDomain.CurrentDomain.BaseDirectory.GetHashCode().ToString() to build the name of the temporary folder it uses to place the DLL. In my application, I have development/production versions of the same application on the same server, which ultimately use the same directory name, so they were conflicting.

I re-wrote the IDeployment implementation myself to use the IIS site name instead, and voila, problem solved. Not robustly tested, but works for me for anyone interested:

    [Serializable]
    public class IISTempFolderDeployment : IDeployment
    {
        public string Path { get; }

        public CustomTempFolderDeployment()
        {
            // Build a folder name to use in the system's temp directory based on the IIS site name (sanitized)
            var appFolder = System.IO.Path.GetInvalidFileNameChars() 
                .Aggregate($"wkhtmltox-{System.Web.Hosting.HostingEnvironment.ApplicationHost.GetSiteName()}",
                    (current, c) => current.Replace(c, '-'));


            Path = System.IO.Path.Combine(System.IO.Path.GetTempPath(), appFolder);
        }
    }

with usage

Converter = new ThreadSafeConverter(new RemotingToolset<PdfToolset>(new WinAnyCPUEmbeddedDeployment(new IISTempFolderDeployment())));

Now instead prod/dev using C:\Windows\Temp\745135165\8\0.12.4.1 The DLL is extracted to C:\Windows\Temp\wkhtmltox-mysitename-prod\0.12.4.1 and C:\Windows\Temp\wkhtmltox-mysitename-dev\0.12.4.1

tofer avatar Apr 19 '21 21:04 tofer

@tofer Is IISTempFolderDeployment class your custom one? Which layer uses the class on your project.

Maybe I used on my project, if i need. It stay as another solution.

mertmtn avatar Apr 21 '21 20:04 mertmtn

@mertmtn yes the IISTempFolderDeployment class is what I wrote for my applications. I used it as a drop-in replacement of the TempFolderDeployment class.

tofer avatar Apr 21 '21 20:04 tofer