ResGen.exe error: An attempt was made to load a program with an incorrect format

ResGen.exe error: An attempt was made to load a program with an incorrect format

  • Comments 65

UPDATE: This issue is fixed in .NET 4.5. As always, feedback is welcome! Please leave your comments in this blog post and report any bugs on Microsoft Connect.

 

Recently, we’ve seen a number of people reporting problems with resource generation in Visual Studio 2010, particularly when they target .NET Framework 3.5 on 64-bit machines.  In this blog post, I will highlight one of the most common errors; when and where it occurs, and how to work around it.  In a later post, we’ll take a look at some other somewhat less common errors, and some background on the differences between the GenerateResource of VS 2008 and that of VS 2010. 

Sample error:

ResourceForm.resx(1436,5): error RG0000: Could not load file or assembly 'file:///C:/Users/sjoiner/Desktop/TestForm/ResTest/bin/x86/Debug/Foo.dll' or one of its dependencies. An attempt was made to load a program with an incorrect format. Line 1436, position 5.

Circumstances under which this error is found:

All of the below conditions must be met:

  • 64-bit operating system
  • Project that contains resource files (Project A)
  • Assembly that is referenced by project A (Assembly B). This can be either a third-party assembly, or another project in your solution that is referenced via a project-to-project reference
  • One or more of Project A’s resources files use types from Assembly B.  For example, if Project A is a form and Assembly B contains controls used by that form. 
  • One of the ‘X’-marked combinations of configuration below must be true.  Note: Building using the Visual Studio IDE is equivalent to building using 32-bit MSBuild.exe.
    VS 2008 VS 2010
Targeting 3.5 or below
VS2010
Targeting 4.0
MSBuild.exe Architecture

32-bit

64-bit

32-bit

64-bit

32-bit

64-bit

Assembly B’s Architecture 32-bit   X X X   X
64-bit X       X  
AnyCPU            

Workaround 1:

Make the assembly you’re referencing (Assembly B) AnyCPU rather than being architecture-specific.

Pros: Easy, means that Assembly B can be loaded by any referencing assembly.

Cons: Not feasible if you made the assembly you’re referencing architecture-specific for a specific reason, or if you’re referencing a 3rd party assembly that is architecture-specific.

Notes on Workarounds 2 and 3:

Workarounds 2 and 3 apply specifically to the scenario where a project targeting .NET 3.5 has a .resx file that references a 32-bit assembly. There is currently no workaround for targeting 4.0 and trying to reference a 32-bit assembly from 64-bit MSBuild or vice versa – aside from changing to use the MSBuild.exe of the architecture you’re targeting.

Please be aware that by forcing ResGen.exe to execute as 32-bit, you are essentially introducing the opposite problem:  ResGen.exe will now error if you try to load 64-bit architecture-specific reference assemblies in it. 

Workaround 2:

Make ResGen.exe 32-bit by:

1. Cd “%ProgramFiles(x86)%\Microsoft SDKs\Windows\v7.0A\Bin”

2. Corflags /32Bit+ /Force ResGen.exe

However, since our current build process has a heuristic that assumes that ResGen.exe is MSIL, just doing the above step will cause a different error (“The specified task executable "ResGen.exe" could not be run. The handle is invalid”) unless you inform GenerateResource that ResGen.exe is now 32-bit via setting the property “ResGenToolArchitecture” to “Managed32Bit”. This can be accomplished by doing one of the following:

1. Adding <ResGenToolArchitecture>Managed32Bit</ResGenToolArchitecture> to a PropertyGroup in the project file of any project that generates resources targeting .NET 3.5 – since the corflags trick affects the bitness of ResGen.exe on a system-wide level, the property must be set for all affected projects as well.

2. OR If running MSBuild.exe directly, passing it using the global property switch: ‘/p:ResGenToolArchitecture=Managed32Bit’

3. OR Setting it as an environment variable in the command window that MSBuild.exe is run from or the VS 2010 IDE is opened from: ‘set RESGENTOOLARCHITECTURE=Managed32Bit’

Pros: Doesn’t require changing the architecture of the referenced assembly

Cons: More complicated; requires baking the workaround either into the project file, or into your build system as a whole.

Workaround 3:

Force the CLR to load all MSIL applications as 32-bit by:

1. Cd “%windir%\Microsoft.NET\Framework64\v2.0.50727”

2. Ldr64.exe setwow

Then, since this also is a way to force ResGen.exe to execute as though it’s a 32-bit process, you must also go through the second part of Workaround 2 (setting ResGenToolArchitecture=Managed32Bit).

Pros: Doesn’t require changing the architecture of the referenced assembly

Cons: Affects how the CLR works for the entire machine. Also the same cons as Workaround 2.

Explanation:

This problem occurs whenever an attempt is made to load a referenced assembly that is of an architecture that is incompatible with the architecture of the currently running process. Since framework reference assemblies are all AnyCPU – so they can be loaded by any architecture with no problem – this typically happens when you have two bit-specific user projects that reference each other, for example one with a form and one that implements a control, and the referencing project contains a resx that uses types defined in the referenced project.  Obviously, the same problem also occurs if your projects reference 3rd-party assemblies that are architecture-specific. 

This problem existed in VS 2008 as well, but it was a lot less noticeable because, since we generated resources in-proc in a typically 32-bit MSBuild.exe (64-bit MSBuild.exe existed, but was not frequently used), in order for this problem to be noticed, the user would have had to have referenced a specifically 64-bit assembly; and even then, a simple workaround would have been to just use 64-bit MSBuild.

However, in MSBuild 4.0, due to the fact that we use ResGen.exe when targeting .NET 3.5 or below, and due to the fact that the ResGen.exe associated with .NET 3.5 is an MSIL application, this error now occurs for anyone who targets .NET 3.5 on a 64-bit machine and has a resx that tries to load types from a specifically 32-bit assembly.

The first workaround removes the bitness mismatch by changing the referenced assembly to be loadable by any application. The second and third workarounds remove the bitness mismatch by making ResGen.exe 32-bit, so that it can successfully load 32-bit assemblies.

I hope this post has provided you with an improved understanding of this error and with the tools you need to work around it. 

Sara Joiner

Software Development Engineer, MSBuild

Leave a Comment
  • Please add 5 and 4 and type the answer here:
  • Post
  • We are now forced to do a workaround to continue the support of Managed DirectX in our existing products that also discourages us from upgrading to 64bit binaries (for newer products) during this transition period.  Please come up with a better solution Microsoft.

  • I was also displeased with the suggested workarounds.

    We were fortunate enough to only have one reference to a third-party x86 DLL in our x86 application, so I was able to write a wrapper class library for what we were using in that DLL.  I was able to compile the wrapper in "Any CPU" mode because it didn't need any resource files, which in turn allowed me to break the main application's direct dependency on the x86 DLL.

    Finally, we can edit ImageLists again!

  • How sad. I have to target .NET 4.0 because I don't want to mess with resgen.exe. Where is SP1 so VS2010 is useable? Or is this all part of a plan to force people to upgrade .NET?

  • None of the workarounds worked for us.  Two of us on my team were the guinea pigs for VS2010 on Win7 x64, and we each attempted to apply the workarounds independently.  So we're stuck with VS2008, since we can't either move to .NET 4.0 (too many customers to force to upgrade) or avoid targeting x86 (3rd party dll).  Not acceptable.  Doing all dev in a VM now - how rubbish is that?

  • All this, because a non-.NET4.0 application has an ImageList which is serialized (base64) with a reference to System.Windows.Forms, version=4.0.

  • I was lucky the class library it complained about in the error, whilst third party, was open source (and we'd added a class to it anyway) so I was able to recompile it for any CPU which fixed the problem.

    Still I agree with the sentiment of the other comments, when is this getting fixed?

    For our app I would gladly move to .NET 4.0 in a heartbeat the only problem is Windows 2000 is not supported and hence until all clients (and potential clients from managements POV) go to XP or higher there is no chance of that happening, sigh!

  • This is unmanagable and makes our migration to 2010 a nightmare.  We can no longer edit forms using the designer in any of our projects that are referencing a 32bit library, and we must target x86 because of this core library.

    What is the plan for a hotfix on this issue?

  • Has there been a release date for the hotfix?  We have to compile as 32bit to reference a 32bit only library and we can't move to .NET 4.0 at this time.

  • I'm getting the same symptom building a .NET 2.0 project. Separate builds for x86 and x64 due to unmanaged library being used. When I enable "Generate Serialization Assembly" (On) I get the error SGEN : error : An attempt was made to load an assembly with an incorrect format: <my assembly dll name>.

  • I'm getting the same symptom building a .NET 2.0 project. Separate builds for x86 and x64 due to unmanaged library being used. When I enable "Generate Serialization Assembly" (On) I get the error SGEN : error : An attempt was made to load an assembly with an incorrect format: <my assembly dll name>.

  • Neither workaround 2 or 3 solve the issue on my system. It seems every time I change the form design the resx gets altered. The only way I can move forward is to restore the previous version of the resx file before I compile. I’m getting away with it at the moment but I guess it comes down to what changes I make to the form.

    This is totally unacceptable and a fix should have been made long ago!

  • Same problem here. I'm trying to migrate a VS 2005 .NET 2.0 x86 project to VS 2010 on Win 7 x64 and it is corrupting always the resx files.

  • Does new vs2010 sp1 beta fixes this issue ?

  • Gokhan, tryed to solve with Sp1 beta: no chance

  • Gokhan, tryed to solve with Sp1 beta: no chance

Page 2 of 5 (65 items) 12345