DLL load error in debug mode ,but release mode is ok - c#

When I use the VS2008 to build my project, I use my own DLL. It works all right in release mode, but when I change it to debug mode, I get an error:
An unhandled exception of type 'System.DllNotFoundException' occurred in DDKWidget.exe
Additional information: Unable to load the DLL "DDKLibA.dll": The specified module could not be found.
The DDKWidget and DDKLibA.dll is my project excutable file and my self-created DLL.
I created my DLL in C++,but I use my it in my C# project, using [DllImport("DDKLibA.dll")].
My OS is Win7 64 bit.
My IDE is VS2008 SP1.
Did anyone encounter this before?
BTW, it was all ok some time ago, but recently, since I re-installed my OS, I started getting these errors. Can any one help me?

This sounds like a problem with 64-bit vs 32-bit mismatch. CLR applications by default get compiled for "AnyCPU" which means that they would automatically run as 64-bit processes on a 64-bit OS.
On the other hand, C++ dlls have to be compiled either for 32-bit or 64-bit and once compiled they stay that way.
You can force a C# app to run in 32-bit mode even under 64-bit OS but that setting can be changed independently for Debug and Release configurations.
My guess would be that your C++ dll is compiled as 32-bit and your Debug setting for your C# dll is also 32-bit but in the Release mode it is set to AnyCPU. That way it would runs as 64-bit process and will not be able to load the 32-bit C++ dll.

where in the filesystem is the dll located? Maybe you copied it to the same directory as your release exe, but forgot to do the same for the debug exe?

The only time I've seen this occur is when a dependent DLL is missing. For example, the release version of your assembly is dependent on foo.dll, but the debug version is dependent on foo-debug.dll. If foo-debug.dll is not installed on the target system, the debug version of your assembly can't be loaded.
I suggest you use a file monitoring utility such as FileMon to see which files the OS is attempting to load when your DLL is loaded.

Related

Platform target x86 and x64 at the same time in Visual Studio 2012

I know how to change the Platform target of my C# project from here: http://msdn.microsoft.com/en-us/library/ms185328.aspx But my question is: Is it possible to target platforms x86 and x64 at the same time in visual studio 2012, so i will have two folders in my Debug directory like this:
Bin\Debug\x86(x86 dlls & exe)
Bin\Debug\x64(x64 dlls & exe)
So i always have the two platforms assemblies available on every build of my project.
EDIT:
using Any CPU: When build my application using "Any CPU" platform and run it on a 64-bit operating system, the process has the extension 32* in Task Manager which means that it is a 32-bit assembly not 64-bit
I tried to build my application using "Any CPU" and when i run it on x64 windows, i found that the process in Task Manager has the extension 32*
You are being confuzzled by the solution configuration name. It defaults to "AnyCPU" for managed projects in VS2012 and up. Which is a fairly accurate name, a .NET project can run on any CPU thanks to the jitter. These configuration names are however only relevant to native projects (C and C++), they pick the kind of compiler that is used to build the project. Since they get built straight to machine code, a different compiler is needed to generate x64 code.
You can select the kind of jitter that's used at runtime, a modern version of Windows is able to run both 32-bit and 64-bit processes. But that's an entirely different setting, it doesn't have anything to do with the configuration name.
Right-click your EXE project, Properties, Build tab. Ensure that the Platform target setting is AnyCPU, untick the "Prefer 32-bit" checkbox if you see it. That removes the jitter choice forcing, your process will now be a 64-bit process on a 64-bit version of Windows. And still run on a 32-bit version, thanks to the jitter. Repeat this setting change for the Release configuration.
Do beware that you'll have to test this, there are various subtleties involved, related to the file system and the registry views that are different depending on the bitness. Having to test both flavors is the one of the reasons why .NET projects default to 32-bit mode.

Strange Visual Studio 2012 behavior when using 32bit dll on 64bit machine

I have a 32bit dll (compiled in Matlab for .Net, so it's a .Net dll). I am on a 64bit machine, only 32bit MCR (Matlab compiler runtime) is installed (I actually had both, but uninstalled them both and reinstalled only 32 bit version to be sure that 64 bit version is not interfering somehow).
I have a solution I'm working on that has many Class Library projects and one Windows Appication project - the main executable. It was set to "Any CPU" with "Prefer 32 bit" checked, as are all the libs "Any CPU" (32 bit check is unavailable for them).
I tried to use the dll in one of the Class Libraries and encountered a problem that I explained here Problems using Matlab compiled lib in .Net (32bit app on 64bit system) (the error message that happens when I try to call constructor of a class from the dll is "An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)").
Now, thiking this may be related to "Any CPU" setting, I've changed the "Target Platform" for the Class Library project that uses the dll and for the Windows Application project to "x86". It didn't help. The error persists!
So, here I have a solution that consists of ~20 Class Libraries (all set to Any CPU), my Class Library that uses the dll (set to x86) and Windows Application (set to x86). When I try to debug my application, it throws an exception.
Now I have made a new test solution in Visual Studio 2012, using .Net 4.5 , that consists of 2 projects: a Windows Application and a Class Library. I've added the usage of the dll to the Class Library, and set both target platforms to x86, and IT WORKS! No exception.
I checked the Output page and they're both loading the same dlls - my dll (exact copy) and MWArray dll (from exact same spot in GAC_32). And exactly same method is called (constructor from my dll).
Now, my question is, why does it work in my test solution, but not in the other solution? What can be different? From what I inspected in project properties, they are identical! Both applications are 32 bit, their Class Library DLLs are 32 bit (I double-checked that with Exe64bitDetector app).
And, here is the wierdest part:
Above I was talking about debugging. Meaning - pressing F5 or clicking Start Debug.
If I actually manually run the program from the disk (from \bin\Debug folder), it works all right! There will be no exception. However, if I use "run without debugging" option, it will still throw an exception!
I double checked the fact that there is no exception by making code like this:
try
{
MyClassInstance = new MyClass();
System.IO.File.Create("APPLICATION.HAS.NOT.FAILED.LOL");
}
catch
{
System.IO.File.Create("APPLICATION.FAILED.LOL");
}
Then I check which file appears in the bin\Debug folder.
That is talking about the main solution of course, in the test solution either of three options work fine without exception.
What is this? I am seriously out of ideas as are all my colleagues. What can be happening here? Where do I look in order to try to solve this mystery?

Loading a 32-/64-bit assembly automatically

My C#/.NET program compiles as AnyCPU, and references Microsoft.TeamFoundation.WorkItemTracking.Client.DataStoreLoader.dll, which is installed with Visual Studio (or Team Explorer). My program must run on computers without VS installed, both 32- and 64-bit, so I have to bring this assembly with my program. It currently runs on 32-bit computers, but not on 64-bit, since it can't load this assembly.
After build, in bin\Debug I get a 32-bit version of this assembly, which VS presumably takes from C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\ReferenceAssemblies\v2.0\Microsoft.TeamFoundation.WorkItemTracking.Client.DataStoreLoader.dll. This is how the program works on 32-bit computers. But my program also runs as 64-bit locally, and the 32-bit assembly gets loaded, how can that be? To check, I wrote me a little PowerShell:
param([string] $path)
$AssemblyName = [Reflection.Assembly]::Loadfile($path).GetName()
write-output $AssemblyName | fl
And ran it as both 32-bit and 64-bit:
> powershell.exe -ExecutionPolicy ByPass -f .\f.ps1 Microsoft.TeamFoundation.WorkItemTracking.Client.DataStoreLoader.dll
(...)
CodeBase : file:///C:/windows/assembly/GAC_64/Microsoft.TeamFoundation.WorkItemTracking.Client.DataStoreLoader/11.0.0.0
> C:\Windows\SysWow64\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy ByPass -f .\f.ps1 Microsoft.TeamFoundation.WorkItemTracking.Client.DataStoreLoader.dll
(...)
CodeBase : file:///C:/windows/assembly/GAC_32/Microsoft.TeamFoundation.WorkItemTracking.Client.DataStoreLoader/11.0.0.0__b03f5f7f11d50a3a/Microsoft.TeamFoundation.WorkItemTracking.Client.DataStoreLoader.dll
Ah, looks like VS installed the assembly to the GAC in both 32- and 64-bit, and the .NET loader knows to load the correct one.
My question: How can I simulate such behavior when I can't install VS?
Option 1: Compile twice as 32-bit and 64-bit, and then I guess I'd get the correct binary in bin\Debug. I'd like not to do that...
Options 2: Deploy these 32/64 assemblies to the GAC in the runtime machine. I'd like to keep my deployment to a simple xcopy...
I am not sure you can redistribute this assembly with your program since they are part of Visual Studio. At least you would need to look at what parts and how you can redistribute the Visual Studio SDK where this assembly is part of. See here and here.
They are also part of the TFS Object Model, but you can't distribute the assemblies from that package either. You can however ask users to download and install that before using your software. And it seems that they are 32 bits only, so you would still need to compile your application as 32 bits.
An alternative would be using the webservices directly. See here. You can call them AnyCPU without problems.
You can try installing the assembly in GAC programmatically by leveraging fusion API.
More details here: http://www.codeproject.com/Articles/8285/GAC-API-Interface

How to run x64 Debug Mode DLLs are "Any CPU"?

I compiled DLLs to be "Any CPU" so they can be run in both x86 and x64, but when I try to run in Debug Mode (x64) it keeps telling me Error while trying to run project: Could not load file or assembly 'Project' or one of its dependencies. An attempt was made to load a program with an incorrect format.
However, when I run the *.exe that I create from the Debug directory or run it in Visual Studio without Debugging, it runs fine, it also works if I run it in x86 Debug Mode. Why would it work in everything but Debug Mode in Visual Studio?
The application is a desktop application, so there is no IIS Application Pool to change to 32-bit.
I have noticed that sometimes when you change configurations, it doesn't change all of the projects. If you go to Build > Configuration Manager in the x64 config, are all of the projects set to build x64 versions?
use corflags.exe to get the PE info for your 'project' dll. It should say PE:PE32+ and 32Bit:0 if it was built as x64. Check to make sure the caller of 'Project' is referencing the project, and not a rogue dll in a build directory elsewhere.
check references first
use corflags to check that reference
report findings

BadImageFormatException when loading 32 bit DLL, target is x86

I have a DLL (FreeType) which is certainly 32-bit (header: IMAGE_FILE_MACHINE_I386).
I want to use it from C# code, using DllImport.
Target of my application is x86, IntPtr.Size is 4, process is 32-bit.
But I get BadImageFormatException (Exception from HRESULT: 0x8007000B). What can be wrong?
Of course I use 64-bit Windows 7.
From what I understand, an assembly specifically built for x86 and running in a 64-bit operating system can only load libraries built for x86 or a BadImageFormatException will be thrown. In a 64-bit OS, an assembly built for Any CPU or x64 will throw the same exception when trying to load an x86 library.
So, assuming nothing incredibly weird is going on, I would ensure that you've set your application to build as x86 by opening the project properties and clicking on the Build tab. Ensure 'Platform Target' is set as 'x86' and not Any CPU.
Alternatively, you could try to find a 64-bit version of the DLL for testing purposes.
Recompile the dll with the option "Any CPU" in Build -> Platform.
OK, seems like a false alert. It was not related to bitness, there was just other DLL missing that freetype depends on. However error messages could be more helpful.
Got the same error when calling a 64-bit C Dll from C#. I had to manually change C# Properties->Build->Platform target from Any Cpu to x64. Apparently Any Cpu is sometimes NoCpu.
Besides, for web-application needs resolve to run 32-Bit Applications in IIS 7. See http://www.fishofprey.com/2009/04/badimageformatexception-in-iis-70-on-64.html
I had a similar error.
I could solve it by adding the ucrtbase.dll or ucrtbased.dll for debug as well as the vcruntime140.dll or vcruntime140d.dll for debug into the directory of the executable.
I think the 140 depends on the version number of Visual Studio you are using.
ucrtbase.dll usually lies in C:\Windows\System32.
vcruntime140.dll lies in C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Remote Debugger\x86\vcruntime140.dll
You can find more information here: http://blogs.msdn.com/b/vcblog/archive/2015/03/03/introducing-the-universal-crt.aspx
I suspect the common cause of this exception has changed in the 8 years since the question was first asked. On my setup using VS 2017 I found that unchecking "Prefer 32-bit" solved the issue:
Uncheck "Prefer 32-bit" in the Build options
This made my 64-bit DLL built from C++ load correctly. Conversely, checking this option should make 32-bit DLLs load correctly.
When you build a native application/DLL something with Visual Studio, it gains a dependency on the "redistributable" package for that version of Visual Studio. That contains DLLs like msvcr100.dll and msvcp100.dll (for various values of 100).
In my case, I had seen those DLLs in the target machine's Windows/system32 directory, so I thought all was well. It turns out that those DLLs were x64! I have no idea why a directory called system32 contains 64-bit DLLs. So I searched my Visual Studio 2010 directory for everything named msvc*.dll, and found x86 versions of msvcr100.dll and msvcp100.dll. I copied those to the target machine (in a place accessible from my program's path) and all was well.
I hope this helps someone else confronted with Microsoft's sheer madness.
you use Properties in C# project, and change "Platform target" to x64.
enter image description here
You can try check the option "Properties" -> "Build" -> "Allow unsafe code".
You have to look at the dependents of the DLL, since one of the dependents may use a 64 bit DLL which makes it incompatible with your project.
visual studio -> tools -> command line -> powershell
dumpbin /dependents your_dll_file.dll
and check these dll's and find out which one is actually not the same with your dll.
I had the same Exception in MS Visual C# Express 2010. I checked all build .dll and .exe files with Dependency Walker and MiTeC EXE Explorer, everything was build for 32bit!
In the end, it was the following line missing in my .csproj file:
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'MY_CONFIG|x86'">
...
<PlatformTarget>x86</PlatformTarget>
...
</PropertyGroup>
I don't know why it was missing ... I guess MS Visual C# Express 2010 is not bugfree ;)

Categories

Resources