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.
Related
I am moving three Windows Services (.NET 3.5) from Windows Server 2003R2, to Windows Server 2012 R2 (.NET 4.5).
The first two went well. Reading registry settings from
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\MyCompany\MyApplication].
Now here´s the funny stuff - the third one only works when I store settings in
[HKEY_LOCAL_MACHINE\SOFTWARE\MyCompany\MyApplication] (whitout Wow6432Node)?
And, if I try to run the service with settings in 32-bit registry it reads the settings ok but I get this assembly binding error instead:
System.BadImageFormatException: Could not load file or assembly 'Oracle.DataAccess, Version=4.121.2.0, Culture=neutral, PublicKeyToken=89b483f429c47342' or one of its dependencies. An attempt was made to load a program with an incorrect format. The other two, using the same dll, works fine.
Any ideas? What is different in the third Windows Service?
Since all applications using the same code to read the registry I don´t think that´s the problem. Her´s the code (simplyfied) anyway.
private string getRegistrySetting(string keyName)
{
string softwareSubkeyName = "SOFTWARE";
using (RegistryKey softwareSubkey = Registry.LocalMachine.OpenSubKey(softwareSubkeyName, false))
{
string lmSubkeyName = "MyCompany\\MyApplication;
using (RegistryKey lmSubkey = softwareSubkey.OpenSubKey(lmSubkeyName))
{
return lmSubkey.GetValue(keyName).ToString();
}
}
}
First, you need to make sure that all your executables have the target platform set to x86 (and not to AnyCPU) on the build tab of the project's property pages (caveat: this is a per-build-configuration setting, you need to set the target platform for both Debug and Release build).
Then you need to make sure that you also deploy the 32-bit version of any third-party components such as Oracle.DataAccess. The reason is that a 32-bit process cannot load a 64-bit dll and vice versa.
The target platform is relevant because it determines if your process will be started as a 32-bit or 64-bit process. If your executable runs as a 64-bit process Registry and file system redirection won't be in place - as a result your process will read and write directly to HKEY_LOCAL_MACHINE\SOFTWARE\ and not to the Wow6432Node subnode.
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
I made a SSIS package that would export data to msaccess. If i try to run the package on its solution project it will execute without error. But when I call the package inside my program, I will get an error
Could not load file or assembly 'Microsoft.SqlServer.DTSRuntimeWrap, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91'. This assembly was compiled for a different processor.
Here is my code:
public void RunPackage()
{
textstring("Locating Package...");
m_worker2.ReportProgress(20);
string PkgLocation;
Package pkg;
Microsoft.SqlServer.Dts.Runtime.Application _app = new Microsoft.SqlServer.Dts.Runtime.Application(); --> I got an exception here.
DTSExecResult pkgResult;
PkgLocation = Properties.Settings.Default.PackageLoc + "\"Package1.dtsx";
textstring("Loading Package...");
m_worker2.ReportProgress(30);
pkg = _app.LoadPackage(PkgLocation, null);
textstring("Executing Package...");
m_worker2.ReportProgress(30);
pkgResult = pkg.Execute();
textstring("Finished...");
m_worker2.ReportProgress(30);
textstring(pkgResult.ToString());
m_worker2.ReportProgress(30);
}
Can anyone point me out the right way. I don't know what is meant by that error. Please enlighten me?
That means, that you mixed x86 and x64 architectures. If your application is x86 (=32 Bit) architecture, you can not use x64 (=64 Bit) compiled assemblies. Try to compile your application with Any CPU or x64.
From MSDN:
To set the Platform target property (C#)
With a project selected in Solution Explorer, on the Project menu,
click Properties.
Click the Build tab.
Choose a CPU type from the Platform target list. The options are Any
CPU (the default), x86, x64, and Itanium.
Here is the complete Link: How to: Optimize an Application for a Specific CPU Type
Important: if you compile for x64 and use x64 assemblies, your application will not run under 32-Bit versions of Windows.
I recently upgraded to SQL 2016 and my VB app stopped running my package. I saved the package no problem to SQL 2016. VB wouldn't run it via the LoadFromSqlServer method. Just reported Could not load file or assembly 'Microsoft.SqlServer.DTSRuntimeWrap' What fixed it for me was to delete the old 12.0 manageddts reference and adding the new 13.0 reference (see image)
Depending on your version of SQL Server Data Tools that is installed on your system, you must add a specific version of Microsoft.SqlServer.DTSRuntimeWrap in your C# Application.
For example if you have SQL Server Data Tools 2010 installed you must add Microsoft.SqlServer.DTSRuntimeWrap 11.0.0.0, and for SQL Server Data Tools 2012
you must add Microsoft.SqlServer.DTSRuntimeWrap 12.0.0.0
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.
I have two applications running on W2k8 R2 x64, one is compiled as 64bit and the other one as 32bit as it has COM dependencies.
In both I'm trying to call:
Process p = Process.Start("telnet.exe", string.Format("{0} {1}", address, port));
In the x64 it works perfectly fine, however in the 32bit one I get a System.ComponentModel.Win32Exception ("The system cannot find the file specified")?
Any idea what's going on here? Even if I call
Process.Start(#"C:\Windows\System32\telnet.exe")
I get the same exception?
Thanks,
Tom
To launch a system32 located 64bit app from a 32bit app (at least on Vista,2k8,7, doesn't work on x64 XP or 2k3) run it from the sysnative directory, i.e. "C:\windows\sysnative\telnet.exe" (alternatively disable Wow64 but that is generally a bad idea).
This drove me crazy... had one project that would find "telnet.exe" without the full path and one that refused to find it (even with the path, or never figured it out). My dev machine is 64-bit.
The problem was the target platform in build.
If it's set to x86 it will not find telnet.
set it to Any CPU it will find telnet.
sometimes you need to set it to x86, this allows your applications to see 32-bit drivers (such as odbc drivers) on 64-bit platforms
Windows Server 2008 does not have a 32 bit telnet.exe client. It only installs a 64bit version in the windows\system32 folder.
\live.sysinternals.com\tools\procmon.exe and/or procexp always has the answer.
Have you looked at the path environment variable in the context of your process? Can you prefix it with the System\SysWow64 path to make it work?
copy telnet.exe to SysWow64 folder