I have a 64bit web application written in c# deployed to IIS on both windows server 2008 (IIS 7) and windows server 2012 (IIS 8).
Part of the application involves accessing an unmanaged c++ DLL from c# code. This call is failing when I deploy to IIS. I get the classic:
An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
I have read many threads on the topic, including:
An attempt was made to load a program with an incorrect format ERROR
“An attempt was made to load a program with an incorrect format” even when the platforms are the same
But I don't think they apply as
I have a 64 bit application.
It's compiled as x64
It's deployed as x64
I have verified it is running under an x64 IIS appPool.
enable32bitapplications is set to false.
Both the c# dll importing and the unmanaged dll are compiled to 64bit.
I have deployed to IIS on the server machines in both Release and Debug mode - no difference.
There are 32 bit dlls in the application, but they are in completely separate projects which are not referenced by, nor reference, the project that is throwing the error.
For additional information, it runs fine on both my local machine in IIS express AND my local machine when deployed through IIS (windows 7), so there is a disconnect somewhere and I can't track it down.
Additional info:
The unmanaged DLL does have dependencies on:
Kernel32.dll
Advapi32.dll
Crypt32.dll
User32.dll
Version.dll
I realize these are 32bit I thought these were 32bit, but on a 64 bit machine these live in System32, so I'm not sure... but if so, how can I get it to compile as the unmanaged DLL itself is compiled to 64 bit.
Also, why would it work locally for me?
Also, I have (just for kicks and skittles) set Enable32BitApplications to True and I get the same error, as my project is a 64 bit project and references a 64bit unmanaged DLL, which can't run in a 32 bit process.
There was an additional dependency for the unmanaged DLL that was a c++ redistributable dll. The copy of that DLL on the machine was 32 bit, once I swapped out the version to be 64 bit, it loaded just fine.
Lesson learned, all dependencies of the DLL must be present and the correct Bitness.
You need to set Enable32bitApplications to true in IIS.
Related
I am trying to create a webservice where the functions are performed by a 64 bit DLL. When I try to build this service i get the error "An attempt was made to load a program with an incorrect format."
But when I run a 32 bit DLL it works fine.
I am trying to run in a visual studio 2012 on .net 4 framework in C#
I have tried changing the app pool settings in IIS and changed build platform target to any cpu. Cannot identify where the problem is coming from. Please provide you assistance. Thank you
Right click on the application pool you are using and go to Advanced Settings. Under (General) there is a setting called Enable 32-Bit Applications. If you're running on a 64 bit OS and this is set to true then the app-pool will be a 32bit process, and therefore your 64bit DLL won't load. Set it to false to make your app-pool a 64bit process.
Also, check the dependencies of the DLL you're building as 64bit. It may be using a 32bit dll/assembly. If you've got any [DllImport] attributes in your code then look at the .dlls they refer to and ensure they're 64bit compatible.
If your web service references 64 bit dlls it must be compiled to x64
Try not to mix AnyCPU compilation with 32 or 64 bit DLL (DLL can be compiled as 32bit or 64bit or both) - behavior will depend on platform and in some environments it will work, in some not.
Hello
I want to create a 64bit application in c# and I wan't to use in it a dll created in C++ builder (32bit). But when I try to load the dll the application crashes. When built in 32bit it works. Is there a way to use this dll in a 64bit app?
No this is not possible. A process in Windows is either 32 or 64 bit and it can only load DLL's which match. Any attempt to load a DLL which does not match will fail and produce an error.
If you need to match 32 and 64 bit code you need to use multiple processes. In this case though I would just make the application 32 bit or the DLL 64 bit
Do you want to build a 64-bit application, or you want to build an application that will run in a 64-bit environment? Your application can run perfectly fine in a 64-bit environment even when the target platform is x86.
You cannot load a 32-bit DLL into a 64-bit process on Windows.
I have never tried it myself, but you might be able to create a seperate 32-bit application that can run in a different process and act as a proxy for the DLL. Your application could then run 64-bit and communicate with the DLL with remote procedure calls over WCF.
If performance is a concern, then your best bet would be to rebuild the DLL in 64-bit, if possible.
I'm trying to get a firebird web application (IIS6 64 bit) to run. However I'm getting bad image format (bit difference incompatability) issues. Has anyone got any advice to get it running.
Details AnyCPU application references the .net firebird driver (through nhibernate) which uses a native 64bit dll. There is a native 32bit dll which I use for local development and it works fine. (I havn't got the 32 version working on the 64 bit server either).
This issue actually formed from how we deployed our website. The site is packaged on a 32bit computer what I didn't realize is that it also packed the 32bit native fire-bird dll's instead of the 64bit ones.
I have a lot of sharepoint web parts etc all of which are compiled for any cpu, they run fine on 32bit sharepoint but moving to server 2008 in 64bit causes the following error:
An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
From my reading they should all work fine?
64-bit processes cannot load 32-bit DLLs and vice versa.
IIS is a 64-bit process on 64-bit hardware. It's possible to configure individual
application pools to run 32-bit, but ...
Sharepoint is most likely to be running 64-bit.
Therefore, your assemblies and all of their dependent assemblies and DLLs will have to run 64-bit.
Note that .NET assemblies that are marked as "Any CPU" will run as 64-bit on 64-bit hardware. Any native DLLs, however, will need to be compiled natively as 64-bit.
You can't mix 32bit and 64bit assemblies. Your only option is to rebuild your binaries to x64.
You can run 32bit binaries/libraries on 64bit OS, but again you cannot mix them together.
My .NET 2.0 application imports unmanaged 32 bit dll.
The dll is loaded (first interop call happens) when user opens a file via a dialog within the application.
When I deploy the application via clickonce with target platform "Any", users on 64 bit windows get BadImageFormatException when trying to open files from the application (at the moment the unmanaged dll is loaded). I understand this is due to incompabible bitness of the 64 bit process and the 32 bit unmanaged dll.
I have redeployed the application using x86 as target platform. As I understand it, this should solve the bitness problem.
BUT
When I run the deployed application built for x86 on 64 bit system, I now get BadImageFormatException immediately before the application even starts. Tested on at least three 64 bit machines. On 32 bit machines, it works with no problem.
When I run the application directly from VS (or not directly, just a normal build, not going via ClickOnce), there is no problem on 64 bit windows when using x86 target platform. The application starts and user can load file - the interop call succeeds.
I have been debugging this for 2 days straight with no result - I have tried on different computers. It seems to consistentnly work on one of the computers I have tried. However, I do not have permanent access to this computer.
I have managed to build the ClickOnce deployment on my computer once and it worked on a 64 bit machine. This was single of maybe 100 tries! Nothing has changed, the only changed variable was that I did the successful build immediately after computer restart.
I did clean/rebuild/restart VS/restart windows MANY times. I have reinstalled VS 2008 and now also the whole OS, it did not help.
EDIT: I have just managed to get one good build (out of next 100 :)) and did comparison between the deployed directories.
The source of the problem is that ClickOnce generates the wrong target platform in the manifest of the main .exe:
<asmv1:assemblyIdentity name="app.exe" version="1.0.4.18" publicKeyToken=".token here." language="neutral" processorArchitecture="<b>msil</b>" type="win32" />
processorArchitecture should be x86.
So the question is how to consistently force VS to generate the correct processorArchitecture in the manifest when deploying.
Can anyone help please?
This was resolved by installing VS 2008 SP1 on 64 bit Windows 7. VS2008 SP1 on XP had the problem on two machines I have tried with.
I had this problem as well, using VS2008 SP1.
In my case I had a 32 bit DLL which had to be compiled as 32 bit and an application that was using it in the same solution.
Even though I specified X86 as the build target for the release build, when I published a 64bit application was compiled and included in the installer.
I found a slightly brutal solution to the problem:
Go into the configuration manager and remove all possible configurations except the one that you want it to build (Debug and release versions).
After doing this I found that the clickonce installer was generated with the correct application.
I hope this helps someone else, I have been battling this problem on and off for months.
I'd suggest to use Reflector to open the main exe deployed by ClickOnce and see the dependencies to make sure you are not deploying the 64 bit version of the dll by mistake.
You must resolve to run 32-Bit Applications in IIS 7. See http://www.fishofprey.com/2009/04/badimageformatexception-in-iis-70-on-64.html
Sometimes the ClickOnce publishing process seems to cache old files from previous Any CPU or x64 builds. Doing a Clean and Rebuild All didn't fix this problem for me. I needed to delete all of the bin and obj folders from my projects and reopen Visual Studio.
We ran into this problem and determined that the subdirectory of the user profile to which ClickOnce deployed our application must have become corrupted, because we were able to deploy the application successfully with ClickOnce when logged in as a different user on the same machine.
We were able to solve the problem simply by deleting the subdirectory of C:\Users\<user>\AppData\Local\Apps under which ClickOnce was deploying our application. In our case, this was C:\Users\<user>\AppData\Local\Apps\2.0.