Program works only on some pc, DLL missing? - c#

I wrote with VS10 the following projects:
a C# (.net 4.0) program which calls
a C++ unmanaged dll, which make use of boost::thread
a setup project which includes the C# executable, the C++ dll, the boost::thread dll and some other files. Moreover during the installation there is a check if the framework .net 4.0 is installed, and if not it will be downloaded.
The compilation (x64 for each of the three projects) is ok, and the program works on my pc (Windows 7 64bit).
I tested the program on some other computers (all Windows 7 64bit) and I noted that:
in the ones with VS10 and Boost the program works
in the ones without VS10 and Boost the program gives an error in the C++ Dll
I think the problem is that some boost Dll is missing. Am I right?
Or the problem could be related to VS?
edit:
I have to mention that the structure of the program is the following:
main form (C#) in which some parameters are set, then a backgroudworker calls
the C++ DLL which do its stuff and uses boost::thread
it does some computations
when it get some results, writes them on file
continue with its computations and so on
the main form has a filesystemwatcher which looks for the results file and do some stuff with the results.
Also, when I get the error, the main form correctly loads and the parameters could be set. The error happens when the backgroundworker starts his work (calling the C++ DLL).
So I'm quite sure that there is no problem with the framework installation.
Update:
It turns out that I forgot to include some DLLs in the setup project. Now, including them the error changed.
Now, at the same point as before (and on the same computers) I get another error:
BadImageFormatException: An attempt was made to load a program with an
incorrect format
I read this article, but I have set x64 in both C# project and in C++ DLL and the setup project has as TargetPlatform x64. Any idea?

VCRedist package is missing on target machine. It should be available in VS SDK directory. Also you may need to install .Net Framework on target machine (.Net Framework contains VCRedist package). If you don't have instalation files for those, they are available on microsoft sites i.e. VC10Redist for x64 is here

In such cases I use the tool Dependency Walker
Launch it and select your executable to discover the missing libraries.
It gives clues indicating what is needed to install then.

If your C++ DLL is dynamically linked to the CRT, then you have to deploy also the VC++ CRT DLL's, i.e. MSVCR100.DLL and C++'s MSVCP100.DLL on the target machine (they are already available on your dev machine, where you have VS2010 installed, so on that machine your C++ DLL loads fine; but you can't assume that on your client's machine the CRT/C++ DLL's are available).
There are several deployment options: you may want to read this documentation on MSDN.

I finally found the solution!
The C++ DLL needs the mpfr library for multiple precision floating point computations with correct rounding.
I was including (shame on me!) the incorrect version of the library (x86) and this was the motivation for the error:
BadImageFormatException: An attempt was made to load a program with an incorrect format
Then in all the computers (three different computers!) in which the program was ok there were both (unlucky and misleading coincidence):
Boost and VS10 installed and
a x64 version of the library in a folder contained in the Path environment variable.
So, in some way the program found the right version of the DLL.
Including the right version of the library in the Setup Project fixed the problem.
Thanks to Kamil Klimek, Stephane Rolland and Mr.C64 for their precious suggestions.

Related

ActiViz.NET.x64 (v5.8.0): Unable to load DLL 'Kitware.VTK.vtkFiltering.Unmanaged.dll'

I'm trying to use the VTK with C# to read and write VTK/VTS files. I created a basic app, and I installed the 64-bit VTK .NET wrapper package which is called ActiViz.NET.x64 (v5.8.0).
The package installed without any problems, and I could access the Kitware.VTK namespace, but as soon as I try to create a VTK object, I got an unmanaged DLL loading error.
An unhandled exception of type 'System.DllNotFoundException' occurred in Kitware.VTK.dll
Additional information: Unable to load DLL 'Kitware.VTK.vtkFiltering.Unmanaged.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
I don't think that the exact code is relevant here, but I got the exception at the following line:
vtkStructuredGrid structuredGrid = vtkStructuredGrid.New();
I'm using Windows 10 x64, Visual Studio 2015, the target .NET Framework is 4.6.2 and I have ParaView 4.1 and 5.2 installed. The DLL in question is in the bin directory of the app, but I also tried to copy it to the Windows/System32 directory, the result is the same.
Is there a way to figure out what exactly the problem is with the dll loading?
If you go to the ActiViz product page you can see the following in the FAQ:
Does ActiViz 64 work with Visual Studio?
Visual Studio is a 32 bits
application, therefore 64 bits control does not work and you need the
32 bits version of ActiViz when using the designer within Visual
Studio. Usually, the 32 bits version is used to design and the 64 bits
version is used for the final compilation.
I also use VTK/ActiViz (C#) on Visual Studio, and it works fine when my program is targeting x86 platforms. However, if I target x64 platforms, the winforms control for the render window disappears, but I can still build the executable. So do this:
1) Install Activiz.NET.x86 from NuGet & target x86 platforms;
2) Create and debug your App;
3) Make a backup of the solution folder;
4) Install Activiz.NET.x64 from NuGet & target x64 platforms;
5) Don't open the designer because it will be buggy (all RenderWindowsControl disappear);
6) Build the solution (Release x64).
So, first I wanted to know where exactly is my process looking for the missing DLL. I used Sysinternals Suite and its Process Monitor.
I referenced VTK in my .NET library which I used in my self-hosted app. The self-hosted app was the start-up project, so the runtime looked for the missing DLL in the app's directory, not the library's, where it actually was.
After I copied the missing Kitware.VTK.vtkFiltering.Unmanaged.dll to that directory, Process Monitor confirmed that the DLL was read successfully, but I still got the same exception as before.
I compared the library's and the app's bin directories, and I figured that only the Kitware.mummy.Runtime.dll and Kitware.VTK.dll were copied there automatically.
I copied all the other VTK DLLs to the app's bin, and then it finally worked.
The exception's error message wasn't detailed in the first place, but I think it is more likely a problem with the ActiViz.NET package.
You should copy all dlls from Activiz Installation bin directory even you don't need to use in your code.
C:\Program Files (x86)\ActiViz.NET 5.8.0 OpenSource Edition\bin
Managed .Net DLL's is a wrapper for unmanaged VTK libraries. Mummy.dll is for this job.

How do I get the proper SQLite assemblies for a project configured for x86 CPU?

Background:
Working in C# using the 2.0 framework and setting up an application to use sqlite. When deployed to certain customer machines I get:
Could not load file or assembly System.Data.SQLite.dll
I am under the impression that there should be no client install of SQLite as long as you've placed the above DLL in the runtime directory. I have tried multiple configurations (x86 DLL compiled into a project targeting x86 cpu - failed on both x86 machines and x64 machines | x64 DLL compiled into a project targeting x64 CPU - failed on both x86 machines and x64 machines | both architecture versions of the DLL targeting Any CPU - failed on both x64 and x86).
I am using SQLite version 1.0.98.0. I'm not sure what relevant code I could post as this is an issue with a DLL reference, but I am happy to upload anything needed to foster a reasonable answer. I have no client computer cpu in mind so if I could get this running as x86 targeting x86 CPU that would be great. Any yes, I have already tried that combination using the correct DLL while making sure it ends up in the runtime folder and it still fails. If I could post more than two screen caps I would show the file as well, but alas I cannot.
I have been searching for quite a while and cannot seem to find an example that exactly fits what I want to do. The question has been asked but not solved. I read that the configuration of the DLL is what causes this and that is why I tried both DLL's targeting both processors. Seeing that this question is asked a lot and I still couldn't find my answer I have to assume a lot of people are in the same position as me so maybe we can work this one out together and give the community a great post on solving this issue.
Assembly information for the x86 configuration
Configuration Manager for x86 CPU
Make sure your dll are deployed properly on target machine. Some time setup compiler (Inno Setup) puts all the files in directory structure in same root folder hence .net can not file dll for expected path and hence it throws file not found exception

C++ /Cli program System.BadImageFormatException

I have a odd problem
platform:.net 4.0, win7 32/64, VS2010
MIPCChannel.dll: C++/cli mixed dll
NewClient.exe: C# which refrenced the MIPCChannel.dll
The Problem is when i deploy my program, someone try to run NewClient.exe gives error:CLR20r3, System.BadImageFormatException
I do below steps:
i deference the MIPCChannel.dll everything goes ok
or i install VS2010 redistribute everything goes ok
but i don't want to reply redistribute, and i want to know where the problem is!
Mixed mode C++/CLI DLLs must be linked against the dynamic runtime. That means you must deploy the dynamic runtime to any machine on which you hope to run such a DLL.
Since you are using VS2010, you don't need to deploy the runtime using the redistributable package, although that is the recommended way to do so. You can instead deploy specific Visual C++ DLLs to the application local folder.
Check if it is x86 or x64 problem. It is likely that you develop in 64 bit environment but deployed that in 32 bit environment.

Want to use COM dll file on deployed machines without registering dll files

I will make this very simple, as it can get quite confusing very quickly. I have a COM dll (made in VB6) that I would like to be able to use through my C# application. Below are the steps I have taken, and the results.
Created COM dll through Visual Basic 6
Added COM dll to .Net application.
Retrieve the "interop.dllName.dll" file generated by .Net in x86/Debug
Added the interop file as a referenced assembly to my CodeDom generated exe file.
The CodeDom generated .exe file worked beautifully on my machine when the .exe file was in the same directory as the interop.dllname.dll file
The CodeDom generated .exe file did not work at all on the deployed machine even though the interop.dllname.dll file existed in the same directory as the .exe file.
Please note:
The original COM .dll is not registered on the deployed machine because the deployed machine does not recognize the COM .dll as a valid dll file.
The COM .dll was made in a x86 environment, while the deployed machine is running in a x64 environment (does this make any difference)?
What my goal is:
I would like to be able to have the CodeDom generated .exe file run without the dependency on the interop.dllname.dll file. Is there any way to store these dll files in memory? Also, I do not want my user to have to register the dll files before they can use the CodeDom generated .exe file. Is there any way of going about doing this?
I appreciate any help on the matter.
Thank you for your time,
Evan
It sounds very much like you have a straightforward 32/64 bit mismatch. Since your COM DLL is 32 bit you need to:
Make sure that the applications that consume this COM DLL target x86.
Register the COM DLL with the 32 bit version of regsvr32 which resides in the SysWow64 folder on a 64 bit machine.
My guess is that you are attempting to register with the 64 bit version of regsvr32. If you make sure everything involved with the registration and consumption is 32 bit then you should be fine.
A 64bit process can't load 32bit dlls. One way to mitigate this is to make sure that the .NET application is compiled for 32bit only (called x86 in Visual Studio)
In order to remove the dependency on the interop dll evaluate the option 'Embed Interop Types' in VS2010. I haven't tested this myself but I do believe it's added for scenarios like yours.
For registration free COM I think article could help as a starting point for you: http://msdn.microsoft.com/en-us/magazine/cc188708.aspx#S1
First issue, the interop.name.dll library, could be easily resolved by decompilation. Just decompile the library and include the source code to your original library. You can use any decompilation tool, IlSpy should do it.
As for COM, there exists a technique called "Registration free COM", it's been introduced in Windows XP, more on this here http://msdn.microsoft.com/pl-pl/magazine/cc188708(en-us).aspx. While it surely works, I am not sure whether or not you'll encounter any issues because of the x86-x64 mismatch.

Why might I get a DLL not found exception on Vista but not XP?

I have an app that relies on several managed libraries. These managed libraries in turn rely on some unmanaged libraries.
When I deploy the app to a machine running XP, it runs fine. When I do the same on a machine running Vista, I get a DLL not found exception.
I've tried both a VS2010 setup project and an NSIS installer to do the deployment and it's the same in both cases.
Why might this happen? What can I do to get around it?
Update - Further details
Both installers check for the installation of .NET 4.0 and install it if need be
The Vista computer is 64 bit, but the installation gets directed to the x86 program files folder as expected
In both cases I have an admin account
The DLLs are kept in the same directory as the executable
As far as I can tell, the files are getting copied to the right directory
Update 2
The full error is at http://pastebin.ca/2046487
The DLL is Audiere.Net.dll, which is one of mine and is a managed library.
I'm not sure if that error means that it can't find Audiere.Net.dll, or whether it can't load it because one of it's dependencies can't be found.
Update 3 - Stuff from Process Monitor
After running process monitor (thanks Mehrdad!) there are several entries which don't have a status of "SUCCESS". Some of these are "NAME NOT FOUND" and some are "PATH NOT FOUND". (It's even querying the PDB files, which I had thought were only used by a debugger.) It's really hard to see which entries might be the one leading to the actual failure. Anyway, I've uploaded the log (filtered to have a relevant path) in case it means something to anyone.
Update 4 - Added .pdb files
So I kinda got desperate and included the .pdb files to the output of the installer. I thought it would be useless, but it actually resulted in a more useful error. Rather than simply saying DLL not found, I now get a BadImageFormatException. Googling this tells me that this is a common problem for binaries compiled on x86 but being run on x64 (as the Vista machine is).
The suggested remedy is to force it to target x86, but Audiere.Net.dll already was. Could the fault lie with the library that it wraps?
Maybe there's some sort of redirection that's not actually letting your app install in the intended folder?
We'd need a bit more detail, but are you installing for the user or the machine? Are you an admin? Where is the DLL normally located?
Edit: Try using Process Monitor to monitor what file is actually being accessed.
If you are running a .Net application, do both computers have the proper Framework installed?
You mention that Audiere.Net.dll is targeted at x86, but what about your executable?
You can obviously recompile your program or use Corflags (part of the framework) to view the current setting on your exe.
Corflags ssd2.exe
Or to set or unset the flag
Corflags ssd2.exe /32BIT+
Corflags ssd2.exe /32BIT-
(Note, if your app is signed with a strong name it won't work unless you use /Force to remove the signature)
The solution turned out to be quite straightforward: one of the unmanaged DLLs needed to be recompiled for x64.
Key steps:
Check process monitor for likely sources of error. Look carefully at the error report that Windows offers to send when the app crashes.
Include the .pdb files for managed libraries. This seemed to result in more informative error messages.
These error messages not only specified which managed library was causing the error, but also indicated that it was a x86/x64 issue. (BadImageFormatException)
Following some sound advice, check that all of the unmanaged libraries are targeting x86. (Mine were, but it's good to be sure.)
Recompile the unmanaged dependencies of the troublesome managed library on an x64 machine.
Write an install script that copies the appropriate (x86 or x64) version of the DLL.
Profit!
Specifics:
The problem I had seemed to be with Audiere.Net.dll, but was actually caused by a problem with libaudieresharpglue.dll.
I use NSIS for installers. To accomplish the architecture specific DLL, I used a header called x64.nsh.
Usual reason is that the dll in question depends on other dlls which are not on the Vista machine (or possibly there but not registered.)
We ran into something simlar and found we needed to download the c++ Redistibuatable Package to get the program to run on windows 7 using 3rd party dlls.
I recall running into a similar issue with SQLite wrapper.
The source of the problem is the 32/64 bit issue of course, and it's the same scenario as the SQLite wrapper is a managed wrapper which makes it processor dependent.
I am guessing that while you're managed lib (Audiere.Net.dll) is compiled for 32 bits, you main application (ssd2.exe) is not.
The installation folder is determined by the configuration of the setup, but if the application project is not strictly configured to compile as a x86 project (usually targeting the default Any Cpu environment) then the application will launch as a 64 bit process, regardless of the installation path. This can be easily verified by looking at the process in task manager on a 64 bit machine, all 32 bit processes have an additional *32 on a 64 bit windows machine (they won't have it on a 32 bit machine).
EDIT: or more easily by looking at the project properties->Build-> Platform Target :)
Anyhow - you should change the project settings for the project that builds ssd2.exe to target x86 and you should be ok.

Categories