TuesPechkin unable to load DLL 'wkhtmltox.dll' - c#

I've been using TuesPechkin for some time now and today I went to update the nuget package to the new version 2.0.0+ and noticed that Factory.Create() no longer resolved, so I went to read on the GitHub the changes made and noticed it now expects the path to the dll?
IConverter converter =
new ThreadSafeConverter(
new PdfToolset(
new StaticDeployment(DLL_FOLDER_PATH)));
For the past few hours I've tried almost all the paths I can think of, "\bin", "\app_data", "\app_start", etc and I can't seem to find or figure out what it wants for the path and what dll?
I can see the TuesPechkin dll in my bin folder and it was the first path I tried, but I got the following error:
Additional information: Unable to load DLL 'wkhtmltox.dll': The
specified module could not be found. (Exception from HRESULT:
0x8007007E)
Where is that dll and now can I get it as the library doesn't seem to contain it, I tried installing the TuesPechkin.Wkhtmltox.Win32 package but the dll still is nowhere to be found. Also I am using this in a asp.net website project so I assume that using the following should work for obtaining the path, right?
var path = HttpContext.Current.Server.MapPath(#"~\bin\TuesPechkin.dll");
Further information: https://github.com/tuespetre/TuesPechkin/issues/57

The Tuespechkin has a zip file as a resource in the Win32 and Win64 embedded packages for the 'wkhtmltox.dll' file.
What it does when you use the Win32 or Win64 Embedded package is unzips the file and places it in the directory that you specify.
I have been putting a copy of the wkhtmltox dll at the root portion of my web app directory and pointing the DLL_FOLDER_PATH to it using the server physical path of my web app to get to it.
According to the author, you must set the converter in a static field for best results.
I do that, but set the converter to null when I am finished using it, and that seems to work.
Tuespechkin is wrapper for the wmkhtmlox dll file.
The original file is written in C++ and so will not automatically be usable in C# or VB.NET or any of the other managed code domains.
The Tuespechkin.dll file DOES NOT contain a copy of 'wkhtmltox.dll'. You either have to use one of the other embedded deployment modules or install a copy of the 'wkhtmltox.dll' in your web app after downloading it from the internet. That is what I do, and it seems to work just fine.
I am using Team Foundation Server, and attempts to compile code after using the Tuespechkin routines will fail the first time because the 'wkhtmltox.dll' file gets locked, but all you have to do is simply retry your build and it will go through.
I had issues with the 32-bit routine not working in a 64-bit environment and the 64-bit environment not being testable on localhost. I went with the workaround I came up with after examining the source code for Tuespechkin and the Win32 and Win64 embedded deployment packages.
It works well as long as you specify a url for the input rather than raw html.
The older package didn't render css very well.
If you are using a print.aspx routine, you can create the url for it as an offset from your main url.
I don't have the source code I am using with me at this point to offset to your base url for your web application, but it is simply an offshoot of HttpRequest.
You have to use the physical path to find the .dll, but you can use a web path for the print routine.
I hope this answers your question a bit.

If you are getting this error -> Could not load file or assembly 'TuesPechkin.Wkhtmltox.Win64' or one of its dependencies. An attempt was made to load a program with an incorrect format.
In Visual Studio Go to -
Tools -> Options -> Projects and Solutions -> Web Projects -> Use the 64 bit version of IIS Express for web sites and projects.

I installed TuesPechkin.Wkhtmltox.Win64 Nuget package and used the following code in a singleton:
public class PechkinPDFConvertor : IPDFConvertor
{
IConverter converter =
new ThreadSafeConverter(
new RemotingToolset<PdfToolset>(
new Win64EmbeddedDeployment(
new TempFolderDeployment())));
public byte[] Convert(string html)
{
// return PechkinSync.Convert(new GlobalConfig(), html);
return converter.Convert(new HtmlToPdfDocument(html));
}
}
The web application then has to be run in x64 otherwise you will get an error about trying to load an x64 assembly in an x86 environment. Presumably you have to choose x64 or x86 at design time and use the corresponding nuget package, it would be nicer to choose this in the web.config.
EDIT: The above code failed on one server with the exact same message as yours - it was due to having not installed VC++ 2013. So the new code is running x86 as follows
try
{
string path = Path.Combine(Path.GetTempPath(), "MyApp_PDF_32");
Converter = new ThreadSafeConverter(
new RemotingToolset<PdfToolset>(
new Win32EmbeddedDeployment(
new StaticDeployment(path))));
}
catch (Exception e)
{
if (e.Message.StartsWith("Unable to load DLL 'wkhtmltox.dll'"))
{
throw new InvalidOperationException(
"Ensure the prerequisite C++ 2013 Redistributable is installed", e);
}
else
throw;
}

If you do not want run the installer for wkhtmltox just to get the dll, you can do the following:
As #Timothy suggests, if you use the embedded version of wkhtmltox.dll from TuesPechkin, it will unzip it and place it in a temp directory. I copied this dll and referenced it with the StaticDeployment option without any issues.
To find the exact location, I just used Process Monitor (procmon.exe). For me it was C:\Windows\Temp\-169958574\8\0.12.2.1\wkhtmltox.dll

In my case, I am deploying on a 64-bit VPS then I got this error. I have solved the problem by installing the wkhtmltopdf that I downloaded from http://wkhtmltopdf.org/downloads.html. I chose the 32-bit installer.

In my case, I have solved the problem by installing the Wkhtmltox for win32 at https://www.nuget.org/packages/TuesPechkin.Wkhtmltox.Win32/

This error: Unable to load DLL 'wkhtmltox.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E) is returned in two situations:
1- Deploy dependency not installed:
For solve this, you can install nuget package "TuesPechkin.Wkhtmltox.Win64" and use this code (for WebApplications running in IIS):
IConverter converter =
new ThreadSafeConverter(
new RemotingToolset<PdfToolset>(
new Win64EmbeddedDeployment(
new TempFolderDeployment())));
// Keep the converter somewhere static, or as a singleton instance!
// Do NOT run the above code more than once in the application lifecycle!
byte[] result = converter.Convert(document);
In runtime this code will copy the dependency "wkhtmltox.dll" in a temporary directory like: "C:\Windows\Temp\1402166677\8\0.12.2.1". It's possible to get the destination of file using:
var deployment = new Win64EmbeddedDeployment(new TempFolderDeployment());
Console.WriteLine(deployment.Path);
2- Microsoft Visual C++ 2013 Redistributable not installed:
As described here:
https://github.com/tuespetre/TuesPechkin/issues/65#issuecomment-71266114, the Visual C++ 2013 Runtime is required.
The solution from README is:
You must have Visual C++ 2013 runtime installed to use these packages. Otherwise, you will need to download the MingW build of wkhtmltopdf and its dependencies from their website and use that with the library. https://github.com/tuespetre/TuesPechkin#wkhtmltoxdll
or, you can install the Microsoft Visual C++ 2013 Redistributable:
choco install msvisualcplusplus2013-redist

Here is AnyCpu version, also support iis-base or winform application
using TuesPechkin.Wkhtmltox.AnyCPU;
...
var converter = PDFHelper.Factory.GetConverter();
var result = converter.Convert(This.Document);
Reference : https://github.com/tloy1966/TuesPechkin

Installing the Visual C++ Redistributable for Visual Studio 2013 resolved the error for me.
https://www.microsoft.com/en-us/download/details.aspx?id=40784

Related

Some clients are unable to load SQLite.Interop.dll

There is an application that uses SQLite. Link to System.Data.SQLite and SQLite.Interop.dll (for x64 and x86 platforms) added statically, version 1.0.112.0. (all 3 files) (SQLite was added to the test project via NuGet, and from there copied to the current project). The System.Data.SQLite and SQLite.Interop.dll files (in the x86 and x64 folders) are present on the client machine. .Net version is 4.7.2.
Most clients work fine, but a few throw an exception with the text "Unable to load DLL 'SQLite.Interop.dll'". I build test versions for x86 and x64 on my machine, in each case SQLite.Interop.dll was loaded from the corresponding folder (If SQLite.Interop.dll does not exist on the corresponding path, then there was an exception).
Where to look to avoid this exception on all client machines?
There is a hunch that the client is missing Microsoft Visual C ++ Redistributable. But later I find out that Redistributable was installed.
The next assumption is that the system can find SQLite.Interop.dll, but an error occurs during loading or initialization, which is interpreted by the wrapper(System.Data.SQLite) as DllNotFoundException.
Maybe the path pointing to the dll is too long?
We had a similar problem when the path that pointed to the dll was too long (More than 255 chars).
After a long search, the cause of the DllNotFoundException was found. This is because SQLite.Interop.dll has a dependency on msvcr120. (Dependency Walker was used to figure this out). But there is one small thing, if the application is for the x64 platform, then this file is expected to be found in the C:\Windows\System32 folder. But if the platform is x86, then the file should be on the path C:\Windows\SysWOW64. I saw that msvcr120 is in the System32 folder and decided that problem is not related to msvcr120.
The simplest solution is to build the application for the x86 platform, and place the msvcr120 next to the exe-file.
I found a better solution to the problem. The corresponding version of msvcr120 is located next to SQLite.Interop.dll in the x86 or x64 folder. Before using sqlite (for example, in the Application constructor or in its overloaded OnStartup() method) we need to add our folder to the PATH environment variable.
var pathVar = Environment.GetEnvironmentVariable("PATH");
string customDllFolder;
if (Environment.Is64BitProcess)
{
customDllFolder = Path.Combine(Environment.CurrentDirectory, "x64");
}
else
{
customDllFolder = Path.Combine(Environment.CurrentDirectory, "x86");
}
pathVar = string.Concat(pathVar, ";", customDllFolder);
Environment.SetEnvironmentVariable("PATH", pathVar, EnvironmentVariableTarget.Process);
This solution is better because we will only use a local copy of msvcr120 if it is not on the user's machine. We can also build an application for both platforms (x86 and x64). This approach can be used for other unmanaged libraries as well.

Programmatically Set VS Installer Project Version on Build Action

I have a C# WPF application, which is written in Visual Studio 2017 (15.9.9) using .Net 4.7. The solution for the application contains two projects - the WPF Project itself and also a Microsoft VS Installer Project that creates a .msi file on the build action.
I have stored the version information for the application project and can return it using the following method
public static string GetVersion()
{
try
{
System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
string version = fvi.FileVersion;
return $"Version {version}";
}
catch(Exception ex)
{
//send error notif to IT dept.
Alert_IT(ex, GetCurrentMethod(), false);
return "0";
}
}
I would like to use the result of this to set the the version information in the Setup project when I build the solution - at the moment it has to be manually entered into the properties of the setup project.
Since we are planning on using setup projects for all our applications, it would be really nice to only have to alter the version in one place for all our projects, ensuring that there are no inconsistencies.
Is it possible to set the version on a setup project programmatically? It would have to be done before the .msi is created.
If this is not possible, do you have any other suggestions as to how to achieve the desired outcome - that the version information for the application need only be set in one place before it is built?
I have seen the advice here, but did not find it specific enough to be helpful.

.NET executables do not work after overwritten with new versions

I faced very strange behaviour - after I overwrite .NET exectables with new versions from network drive it cannot start.
When try to start from Windows Explorer it shows me following error:
[Window Title]
C:\Programs\zzz\clients.net\zzzNet.exe
[Content]
C:\Programs\zzz\clients.net\zzzNet.exe
The application has failed to start because its side-by-side configuration is incorrect. Please see the application event log or use the command-line sxstrace.exe tool for more detail.
I tried to execute following commands:
SxsTrace Trace -logfile:SxsTrace.etl
SxStrace Parse -logfile:SxSTrace.etl -outfile:SxSTrace.txt
And got following result:
=================
Begin Activation Context Generation.
Input Parameter:
Flags = 0
ProcessorArchitecture = AMD64
CultureFallBacks = en-US;en;ru-RU;ru
ManifestPath = C:\Programs\zzz\clients.net\zzzNet.exe
AssemblyDirectory = C:\Programs\zzz\clients.net\
Application Config File = C:\Programs\zzz\clients.net\zzzNet.exe.Config
-----------------
INFO: Parsing Application Config File C:\Programs\zzz\clients.net\zzzNet.exe.Config.
INFO: Parsing Manifest File C:\Programs\zzz\clients.net\zzzNet.exe.
INFO: Manifest Definition Identity is (null).
ERROR: Line 0: XML Syntax error.
ERROR: Activation Context generation failed.
End Activation Context Generation.
It is quite simple .NET application (1 exe + 8 dll files). It was built for .NET 3.5 Client Profile.
I not defined any special "manifest" there. Just clicked "New Windows Forms Project" in Visual Studio and developed it.
Also app.config does not contain anything special - only primitive standard settings - appSettings and userSettings sections.
On PC where I developed it all is perfectly works. Problems only began when I copy these binaries to this particular VM and try to start.
Also please note - these executables were not installed in GAC or such, I just copied them into a folder on VM and started. And when it was 1st time all was working fine.
So, the problem pattern is following:
Copy .NET execuatbles to new VM (it is Win 7 x64), run it, all is working fine. Close it.
Build new version of .NET execuatbles on host PC, copy new .NET execuatbles to VM (with files overwriting).
Try to start - got mentioned problem.
After some shaman-style actions (like OS reboot, etc) it begin to work but why that happened at all?!
Why replacing .NET executables with new versions is causing SUCH HUGE PROBLEMS?!
Also the BIG QUESTION - is there any special procedure to replace .NET executables to keep them working? Because it is a new app development, I do not want lost so much time on every new executables installation. :-\
Could you please help? Because it looks completely weird!
Thank you in adance.
PS. I checked all VS projects - all they have PlatformTarget=AnyCPU. Also in run-time I can see ProcessType=MSIL (I show this info in AboutBox for application). So, there is no mix of x86/x64 binaries.
It seems that was related to mapped network drive behavior.
When I copied new files from network drive folder it copied wrong files - a strange random mess of new files and older ones (which were there before I updated them on VM host).
The scenario to make it working:
on VM: delete all files in a folder on network drive
on VM host: copy new files into a folder which is mapped as network drive on VM
on VM: copy files into target folder
on VM: run application - it works now
Weird thing. I remember I have seen something similar with Windows Explorer on Windows 2008 behaviour when copying updated win32 binaries.

Beginner ILNumerics: install under VS2012

I am very much interested in ILNUmerics and would like to try the free version, but I am having troubles.
I have started with a console application and was trying to run the 'hello ilnumerics'console application but I noticed that VS fails to find MKL libraries.
I am using VS2012 under Windwos 8 (through Bootcamp on a MacBook Pro mid 2010; should it be relevant); I have installed the NuGet Packages extension from the Project solution. Then right-click on references in the solution explorer, 'Manage Nu Get Packages', fron online/search found ilnumerics in various versions. I chose 'ILNumerics' and install. I got 'ILNumerics' and 'ILNumerics.Native' added to my project. Then I can see ILNumerics under 'References' in Solution Explorer and also get two new folders /bin32/ and /bin64/ they both contain two DLLs named: libiomp5md.dll and mkl_custom.dll. I have checked their
'Copy to Ouput Directory' property and they are all set to 'Copy if newer'.
Apparently mkl_custom is not found. I write the following code, taken from the quickstart guide:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ILNumerics;
namespace ConsoleApplication3
{
class Program : ILMath
{
static void Main(string[] args)
{
ILArray<double> A = array<double>
(new double[] { 1,1,1,1,1,2,3,4,1,3,6,10,1,4,10,20} ,4, 4);
ILArray<double> B = counter(4, 2);
ILArray<double> Result = linsolve(A, B);
Console.Out.WriteLine("A: " + Environment.NewLine +
A.ToString());
Console.Out.WriteLine("B: " + Environment.NewLine + B.ToString());
Console.ReadKey();
}
}
}
and I get this exception:
An unhandled exception of type 'System.DllNotFoundException' occurred in ILNumerics.dll
Additional information: Unable to load DLL 'mkl_custom': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
If I do not invoke linsolve the ToString method of ILArray does work: if I comment // ILArray Result = linsolve(A, B);
I get the two matrices printed on the screen.
I have also tried to compute the determinant of a matrix and got the same exception: apparently any time I call mkl_custom VS is not capable to find it.
Any help/hint, please?
Also, is it necessary to install ILNumerics through NuGet on any project added to the solution? Would it be possible to install it locally once for all and then add the reference if necessary?
Two options:
1) Make sure, all binaries are accesible as intended: ILNumerics uses AnyCPU targets and chooses the platform dependend subfolder by adding the "bin32" / "bin64" directories to the PATH envoronment variable on startup. Possibly there is something failing on your machine? You can make sure by placing the correct binaries (depending on your platform) directly into the output path manually.
2) In case the error persists: mkl_custom.dll depends on some other dlls itself. One (libiomp5md.dll) is delivered with the ILNumerics nuget package. Others are expected to exist on your system: KERNEL32.DLL and MSVCR110.DLL. Make sure, you have these! If the kernel dll was missing -> call it a miracle and reinstall your system. If the msvcr110 is missing -> go here and install the "Visual C++ Redistributable for Visual Studio 2012".
In case the problem persists, you may file a bug on the ILNumerics bugtracker, because, the runtime should be there, as you wrote you are using VS2012. Possibly it is a versioning problem though.
EDIT: Since version 4.0 ILNumerics does not deploy the native binaries in bin32/ bin64/ subfolder anymore but installs all native dependencies systemwide into the GAC and System32/WOW folders. The old scheme will still work (for compatibility with old projects) though. But it is not necessary anymore to deal with any dependancies for ILNumerics explicitly. They should simply be found at runtime.
Like numbers303 said, ILNumerics.dll can't find a required dependency. You can brute force fixing this dependency by copying the required DLLs to the same directory as the ILNumerics.dll as a post build step, but I think there's a more elegant solution.
A VS2010 .NET console solution gets created by default with the x86 configuration. Compiling and running the ILNumerics example Hello ILNumerics! code with this configuration results in a DLL not found exception (mkl_custom.dll).
Re-targeting the solution via configuration manager to 'Any CPU' fixed the issue for me:
In Solution Explorer, right click on the solution and select properties. Select Configuration Properties and click on the Configuration Manager... button in the upper right hand corner. Make sure that the project that uses ILNumerics has the 'Any CPU' selected. If 'Any CPU' isn't available as a selection, select '' from the pulldown and create an 'Any CPU' platform based on your current platform. Usually this just means accepting the default in the 'New Project Platform' dialog. You'll probably also want to modify the 'Active solution platform:' to contain an 'Any CPU' target as well.
Rebuild/run.
In my case it helped to install "Visual C++ Redistributable for Visual Studio 2012" although I work with Visual Studio 2010 with the corresponding "Visual C++ Redistributable for Visual Studio 2010" installed. Which worked fine as long as the mkl_custom.dll is not needed. But colleagues of mine dosn't have this problem without having the 2012 Redistributable installed.

Import DLL c++ on VSC# 2010 (AdminPaq SDK )

I'm trying to import a library to my WCF project, the DLL was provided by Adminpaq.
i'm using the next following code:
[DllImport("MGW_SDK.dll", EntryPoint = "fInicializaSDK")]
public static extern int fInicializaSDK();
When i debug the app say the next error : Unable to load DLL The specified module could not be found.
I've ready on web that the error could be by dependece but on the SDK documentation display a list of some files that must be added to the root project i'm currently adding al of them
Some info:
Dll is build on: c++
Proyect type: c# Application service MCF
I'm using: Windows 7 ultimate x64
Any further information required please don't hesitate to ask.
You are right, usually it is related to some other library that your MGW_SDK.dll depends on. Try these:
1) Install the Microsoft Visual C++ redist (2005, 2008 or 2010, depending on which VS was used to build that dll)
2) If that does not help, try using dependency walker tool to see which files are missing (http://www.dependencywalker.com)
I hope that helps.
You must type the full and original path of the DLL, for example: #"C:\Program Files (x86)\Compacw\AdminPAQ\MGW_SDK.dll"
you must install AdminPaq and have a registered license, after that the error will dissapear

Categories