I created an Azure function to do HTML to Pdf conversion and am getting the following error in Azure function logs:
Access to the path 'C:\Program Files (x86)\SiteExtensions\Functions\3.20.0\32bit\wkhtmltopdf' is denied.
Code on the functions is pretty basic:
var htmlToPdf = new NReco.PdfGenerator.HtmlToPdfConverter();
var pdfBytes = htmlToPdf.GeneratePdf(req.BodyHtml);
return new FileContentResult(pdfBytes, "application/pdf")
{
FileDownloadName = "test.pdf"
};
Any help would be greatly appreciated
The same code works in Visual Studio debug locally
error stack:
Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Exception while executing function: HTMLtoPdfConverter ---> System.UnauthorizedAccessException: Access to the path 'C:\Program Files (x86)\SiteExtensions\Functions\3.20.0\32bit\wkhtmltopdf' is denied. at System.IO.FileSystem.CreateDirectory(String fullPath, Byte[] securityDescriptor) at System.IO.Directory.CreateDirectory(String path) at NReco.PdfGenerator.HtmlToPdfConverter.EnsureWkHtmlLibs() at NReco.PdfGenerator.HtmlToPdfConverter.GeneratePdfInternal(WkHtmlInput[] htmlFiles, String inputContent, String coverHtml, String outputPdfFilePath, Stream outputStream) at NReco.PdfGenerator.HtmlToPdfConverter.GeneratePdf(String htmlContent, String coverHtml, Stream output) at NReco.PdfGenerator.HtmlToPdfConverter.GeneratePdf(String htmlContent, String coverHtml) at NReco.PdfGenerator.HtmlToPdfConverter.GeneratePdf(String htmlContent) at Showcast.Azure.Functions.HTMLtoPdfConverter.Run(HtmlToPdfConverterArgs req, ILogger log) in C:\Showcast\Code\showcast.web\Showcast.Azure.Functions\HTMLtoPdfConverter.cs:line 26 at Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker`2.InvokeAsync(Object instance, Object[] arguments) in D:\a_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionInvoker.cs:line 52 at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.InvokeWithTimeoutAsync(IFunctionInvoker invoker, ParameterHelper parameterHelper, CancellationTokenSource timeoutTokenSource, CancellationTokenSource functionCancellationTokenSource, Boolean throwOnTimeout, TimeSpan timerInterval, IFunctionInstance instance) in D:\a_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 581 at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithWatchersAsync(IFunctionInstanceEx instance, ParameterHelper parameterHelper, ILogger logger, CancellationTokenSource functionCancellationTokenSource) in D:\a_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 527 at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstanceEx instance, FunctionStartedMessage message, FunctionInstanceLogEntry instanceLogEntry, ParameterHelper parameterHelper, ILogger logger, CancellationToken cancellationToken) in D:\a_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 306 --- End of inner exception stack trace --- at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstanceEx instance, FunctionStartedMessage message, FunctionInstanceLogEntry instanceLogEntry, ParameterHelper parameterHelper, ILogger logger, CancellationToken cancellationToken) in D:\a_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 352 at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.TryExecuteAsync(IFunctionInstance functionInstance, CancellationToken cancellationToken) in D:\a_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 108
This error
Access to the path 'C:\Program Files (x86)\SiteExtensions\Functions\3.20.0\32bit\wkhtmltopdf' is denied.
indicates that you use "NReco.PdfGenerator" nuget which includes wkhtmltopdf binaries for Windows and it tries to extract them on the first GeneratePdf
method call but default location for this binaries (which is usually app's folder with DLLs) is not accessible for write.
To fix this it is enough to specify another location for wkhtmltopdf binaries, in most cases temp folder is accessible for write and can be used for this purpose:
var htmlToPdf = new NReco.PdfGenerator.HtmlToPdfConverter();
htmlToPdf.PdfToolPath = Path.Combine( Path.GetTempPath(), "wkhtmltopdf" );