The .NET Assembly “Incorrect Format” Error

If you get this error in a Windows Forms project…

Look in your Project–>Properties (ALT+F7) and go to the “Build” tab.
You’ll see the “Platform target”

– If it’s set to “x64”, then make sure you reference the 64-bit Chilkat assembly.
– If it’s set to “x86”, then make sure you reference the 32-bit Chilkat assembly.
– If it’s set to “Any CPU” and the “Prefer 32-bit” checkbox is checked, then your app will run in 32-bit mode and you should reference the 32-bit Chilkat assembly.
– If it’s set to “Any CPU” and the “Prefer 32-bit” checkbox is NOT checked, then your app will run according to the computer (64-bit or 32-bit). It is unlikely you’re developing on a 32-bit Windows computer, so in that case you’d reference the 64-bit Chilkat assembly.

Dynamically Loading a 32-bit or 64-bit .NET Assembly at Runtime

The Chilkat .NET assembly is a mixed-mode assembly, meaning that it exposes a managed API, but the inner core is native. Therefore, as for any DLL, a 32-bit process must load a 32-bit DLL, and a 64-bit process must load a 64-bit DLL.

On a 32-bit system, there is never any choice and therefore this whole subject is moot.

On a 64-bit system, a 100% managed .NET app can run as either a 64-bit process or as a 32-bit process. Visual Studio projects have a setting named “Prefer 32-bit”, which is by-default ON, which means the app will always run as a 32-bit process. In that case, it is the 32-bit DLL that must be loaded (always), and again this subject is moot.

I recommend this: If your app does not use more than 4GB of memory, then simply choose to run 32-bit everywhere. You have better things to do with your time. Performance is usually just as good (if not better) running 32-bit.

I also recommend this: As time goes on, it gets more and more difficult to find yourself actually running on a 32-bit system. I’m sure it’s been many years since it’s been possible to buy a new computer running 32-bit Windows, and Microsoft is ending support for the OS’s what can run 32-bit Windows. So.. if your app will NEVER encounter a 32-bit system, and it needs more than 4GB of memory, then uncheck the “Prefer 32-bit” setting in your Visual Studio app, and ALWAYS run 64-bit. Again, you have better things to do with your time than monkeying around with additional unnecessary complexity.

If you’re in the situation where you desire either 32-bit or 64-bit, then there are two solutions:

  1. Make sure the 32-bit Chilkat DLL is distributed with your app to systems where it will run 32-bit, and the 64-bit Chilkat DLL is distributed with your app to systems where it will run 64-bit. Or…
  2. Dynamically load either the 32-bit or 64-bit DLL at runtime. Here are links to two possible solutions for doing so.

http://cknotes.com/dynamically-loading-net-assembly-32-bit-or-64-bit/

http://www.codeproject.com/Articles/528178/Load-DLL-From-Embedded-Resource

.NET Assembly Incorrect Format Error

"Could not load file or assembly 'ChilkatDotNet2, Version=9.3.0.0, Culture=neutral,
PublicKeyToken=eb5fc1fc52ef09bd' or one of its dependencies.
 An attempt was made to load a program with an incorrect format."

The “incorrect format” error is a 32-bit vs. 64-bit mismatch.  It means the application is trying to load a 64-bit .NET assembly into a 32-bit process,  or the reverse (a 32-bit assembly into a 64-bit process).

Possible solutions are:

1) Target your app for x86 instead of “Any CPU”.  If you do this, then your application will run as a 32-bit process regardless of the machine architecture and you may always use the 32-bit Chilkat assembly.

2) If you really need to target “Any CPU”, then make sure to deploy the 32-bit Chilkat assembly w/ your app on 32-bit systems, and deploy the 64-bit Chilkat assembly to 64-bit systems.

3) If your app is running within ASP.NET or a Windows Service and you’re not quite sure whether it’s 32-bit or 64-bit, then install the 32-bit Chilkat assembly in the 32-bit GAC (Global Assembly Cache), and also install the 64-bit Chilkat assembly into the 64-bit GAC.  The .NET runtime will automatically look in the correct GAC and will find the correct assembly.

Incorrect Format Error when trying to load .NET Assembly

This Chilkat blog post explains the following error:

"Could not load file or assembly 'ChilkatDotNet2, Version=9.0.8.0, Culture=neutral,
PublicKeyToken=eb5fc1fc52ef09bd' or one of its dependencies.
 An attempt was made to load a program with an incorrect format."

When a DLL is loaded, it is mapped into the process’s address space. If the process is running in a 32-bit address space, the DLL must also use a 32-bit address space. (In other words, it should be a DLL compiled for the Win32 platform.) If the process loading the DLL is running in a 64-bit address space, the DLL must match — i.e. it should be a DLL compiled for the x64 platform.

This applies to both .NET assemblies *and* ActiveX DLLs.

64-bit Windows is capable of running applications in both 32-bit mode and 64-bit mode. If your application is running in a 32-bit address space, the DLLs it loads must also be 32-bit. If your application is running in a 64-bit address space, the DLLs it loads must also be 64-bit. Just because your application is running on 64-bit Windows does not mean it requires a 64-bit DLL — the determining factor is the process’s address space.

For example, let’s say you’ve configured IIS to run its worker processes in 32-bit mode. In that case, your ASP or ASP.NET apps would require 32-bit DLLs. If IIS is running in 64-bit mode, then 64-bit DLLs are needed.

Important: The “Incorrect Format” error is only caused by one thing: The address space (32-bit or 64-bit) of the process loading a DLL does not match the DLL’s address space. Quite often developer get stuck on this problem because they don’t know one or both of the following:

  1. Is your application running in a 32-bit address space or 64-bit?  You’ll need to know this.  If running in 32-bit, you can ignore the 64-bit DLL builds altogether because you’ll never need them.  For .NET applications in Visual Studio you may target “win32” instead of “Any CPU” to force your executable to run in a 32-bit address space.  In 99% of all cases, this is not an issue — does your application really need more than 4GB of memory?
  2. You’re not loading the DLL you *think* your loading.  With ActiveX, are the registry entries created by regsvr32 really pointing to the DLL in the filesystem that you’re intending to use?  (For more information: regsvr32 registry entries)  With .NET, is the assembly found by the .NET runtime loaded from the GAC?  Is it found in the directory where you think it should be found?

About the Windows registry and ActiveX:  The following applies only to ActiveX DLLs and not .NET assemblies.  .NET assemblies are not registered with regsvr32 and have no registry entries required for locating the DLL when loading.

A 64-bit Windows system has two separate registries — one for 32-bit processes, and one for 64-bit processes.  The reason for this makes sense if you think about it..   Let’s say your application instantiates an instance of an ActiveX component by calling CreateObject(“Chilkat.Ssh”).   If your application is running in a 32-bit address space, the registry entries for “Chilkat.Ssh” should point to a 32-bit DLL in the filesystem.  However, if your application is running in a 64-bit address space, the registry entries should point to a 64-bit DLL.  How can you do both with one registry?  The answer is to have separate registries — one for 32-bit and one for 64-bit.

Therefore, when you register a DLL with regsvr32 — did you register the 32-bit DLL in the 32-bit registry, or did you register the 64-bit DLL in the 64-bit registry?  You’ll need to get it right.  When you run regsvr32 on an x64 system, you’re running the 64-bit version by default.  (That’s a bit confusing because of the “32” in the regsvr32 name…)  To run the 32-bit regsvr32, do this:

cd \windows\syswow64
regsvr32 c:\filename.dll

(Note the stupidity of it all — the default regsvr32 is 64-bit and resides in the \windows\system32 directory.  Note the “32” in system32 and the “32” in regsvr32 — quite misleading.  However the 32-bit version of regsvr32 is found in the \windows\syswow64 directory.  Note the “64” in the directory name.  That’s also misleading.  Ughhh!)

More information about: regsvr32 or ActiveX object creation errors.