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 6 and 8 and type the answer here:
  • Post
  • This problem is also going to be compounded by the crazy decision to default all new projects in VS2010 to target only 32-bit.

    People literally begged the team not do this:

    connect.microsoft.com/.../new-c-console-application-targets-x86-by-default

    connect.microsoft.com/.../platform-target-is-defaulting-to-x86-rather-than-any-cpu

  • That should be just simply flipping the switch to Any CPU. This is only for applications. Class libraries still default to Any CPU.

    If you are like me, then you have your own starting templates anyway.

    To setup your own templates, create a new C# project and set it up the way you like it. You can include code and what-not. Then, click "Export Template..." from the "File" menu. Enter the information in the dialog and finish.

    Now you can click "New Project..." from the "File" menu, and you will see your template.

    Chuck England

    Visual Studio

    Program Manage - MSBuild

  • Thanks a ton for the workarounds

    We use x86 because we need edit and continue, so change to AnyCpu is not an option, but using the Workaround 2 works perfect for us :)

    Cheers

  • I'm have issues with this problem.

    Workaround 1 and 3 are not an option for me. Trying to compile after Workaround 2 produces a "Failure to execute command: ""C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\ResGen.exe" /useSourcePath "...[very long list of parameters]"

    Is anyone else having this issue?

  • Holy crap, it worked! ... but, I'm looking forward to the patch (or SP1 or whatever) ;)

  • Just have a go with Workaround 2, its was working OK now after half year pain.

    We are still looking for an patch or fixes for VS2010 in future.

    MS can't just leave us with this.

  • This is unbelievable. Microsoft team has marked the reported bug connect.microsoft.com/.../error-in-control-resx-file-when-adding-imagelist as Closed (Won't fix).

    This is a some kind of a lame joke. :-\

  • How about who need to mantain one of this "bugged" projects and also make a new one fully 64bit in vs2010 every time we use one or the other we need to apply or toggle this fix.

    Please MS give us a patch to fix this issue.

    Thanks in advance.

  • I seem to run in a different problem with the new RESX file. I get an error "Strong name validation failed". It happens when I build my solution with the Delay-Sign attribute

    [assembly: AssemblyDelaySign(true)]

    Here is the story:

    I upgraded my solution from VS2008, WinXP, 32bit TO VS2010, Win7, 64bit.

    When I make modifications on WinForms that generate new RESX files, or update the RESX files, I'm running into problems.

    A Debug build with VS2010 was no problem. However for Release mode I have to use a delay-signing process. Now that process gives errors on new RESX files that are generated with VS2010. (Again note that old RESX files do NOT show this behaviour)

    (CoreResGen target) Search.resx(176,5): error RG0000: Could not load file or assembly xxx.Controls, Version=1.5 0, Culture=neutral, PublicKeyToken=7acfcxxabace048' or one of its dependencies. Strong name validation failed. (Exce on from HRESULT: 0x8013141A) Line 176, position 5.

  • This issue is getting much worse for us. Every time someone touches a winform with an ImageList it is checked out from source control. Since we have multiple checkout enabled in TFS (the default), this is resulting in almost every user in our team having the winforms checked out. We’ve lost the ability to meaningfully track changes.

    A postponement of this bug is not acceptable and we must get a fix for this issue.

  • This issue is an absolute nightmare for us.  Every time we edit a form we must go back and edit the resx file manually to change it back to 2.0.0.0. Cannot get the suggested work arounds working for us. It seams like our only option is to wait for an SP to fix this or go back to 2008. I wish we did not upgrade to 2010. MS Please fix this issue asap!

  • I agree MS please post a hotfix for this issue.  It is costing us a fortune in lost time to have developers manually change the imagelist resource to correct the issue.

  • This also fixes slow build issues with Server 2k3 x64 and VS 2010

  • None of the above fixes worked for me unfortunately. After much tearing of hair, I finally got the idea to copy the C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin folder from another box where I wasn't seeing the problem (yet).

    Problem solved...

  • Has Microsoft fixed this issue yet? Workaround is not a SOLUTION!!!! We need fixes.....

Page 1 of 5 (65 items) 12345