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.