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 1 and 3 and type the answer here:
  • Post
  • I get screwed everytime I upgrade.

    First I upgrade to VS 2010 and have nothing but problems with VSTO and building setup projects because of the upgrade. I have lost hours to days because of this. It is still a problem that haunts me.

    Now, I upgrade from XP to Windows Ultimate, I change my OS to 64 bit instead of 32 bit so I can utilize my machine, and now I have to deal with problems because of it.

    Now I remember why I always waited until the 3rd service pack of windows came out to upgrade. This fix is impossible. I have 87 projects in one of my solutions and now I have to go figure out who is A and who is B.

    I can't wait for 128 bit to show up.

    Microsoft employees need to unionize to make the software better quality.

  • Just got off the phone with Microsoft, no planned hotfix for this, they plan to address in VS2011. I am still discusing with them, if this is important to you please contact microsoft and let them know. We are a library vendor with a 32bit dependancy so the work arounds are not acceptable to us.

  • This is ridiculous. They must at least provide some options in the IDE that apply the workarounds for you as no amount of fiddling in a command prompt seems to work on my system. I’ve got many 32-bit dependencies which have 32-bit dependencies within them and that’s never going to change and I can't move up to .NET 4 right now. What am I suppose to do? Reinstall my OS with 32-bit Windows 7?

  • This is absurd MS! Shame on you! Give us a fix! None of the three work-arounds works for me. I can't get a single one of these working! I have had to go back to my XP Virtual to get ANYTHING done.

  • We need fix, please fix it ASAP!!!!!!!!

  • "... 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."

    So, if your a developer and your dev machine is 64-bit, you can not target 32 bit applications. WOW! MS admit you messed up and fix this.  You sell an OS that supports 32 & 64 bit applications, yet your dev product will error if developing an application that utilizes 32 bit assemblies.

    If you develop with W7x64 and target 32-bit applications and are thinking about migrating to VS2010, let us save you a ton of time and heartache - don't.

  • I can only echo the remarks above: none of the fixes work for us, we have had to go back to VS2008. That was after many days wasted trying to get our libraries to work, and serious money spent on upgrading. Unacceptable.

  • The fixes don't works for us. Is there really no fix from Microsoft? Please fix this problem!! Thx

  • Put this line in your project file under the node "PropertyGroup" by manually editing it, and you will be fine.

    <ResGenToolArchitecture>Managed32Bit</ResGenToolArchitecture>

  • I tried putting this in my vbproj file but no change.

    <?xml version="1.0" encoding="utf-8"?>

    <Project DefaultTargets="Build" xmlns="schemas.microsoft.com/.../2003" ToolsVersion="4.0">

     <PropertyGroup>

       <ProjectType>Local</ProjectType>

       <ProductVersion>9.0.21022</ProductVersion>

       <SchemaVersion>2.0</SchemaVersion>

       <ProjectGuid>{71887E1F-4FA8-4DAE-9610-656636F73B1F}        

       <ResGenToolArchitecture>Managed32Bit</ResGenToolArchitecture>

    </ProjectGuid>

    Is the above what you mean?

  • Recently converted 4 of our developer's laptops from XP to Win7-64.

    Each of them has this issue when trying to build our library.  Also had the same issue running WcfSvcHost.exe and are unable to make changes to our WCF interface from a 64bit machine.

    None of the work-arounds are an option for us.  

    They have indicated the bug is being worked on:

    connect.microsoft.com/.../error-when-compiling-resx-file-seems-related-to-beta2-bug-5252020

    Hopefully this is fixed in SP1.  If not, perhaps we'll be forced to downgrade to 32 bit.

  • There seems to be a workaround that involves modifying the resx file that works: connect.microsoft.com/.../error-when-compiling-resx-file-seems-related-to-beta2-bug-5252020

    (Read the comments)

  • Finally something that has worked for me- as per Pellet21’s post on connect, simply edit the imagestream and change the 0 to a y!

    OK MS, so the fix didn’t make SP1, but you can’t seriously be suggesting we have to purchase the next full release of Visual Studio to solve a critical bug? What kind of update strategy is that? It would actually be unprecedented in the history of Visual Studio and if I did the same with my software I’d lose all my customers. Your product is faulty, the reputation of visual studio is in question and your update policy is a shambles. Get with reality and do the honourable thing.

  • I have lost almost 3 days after upgrading to VS2010 + Win7-64 trying to figure out what is wrong with .resx compiling when targeting x86.

    Will you M$ pay for my lost of time ? Why have i to purchase VS2011 just to solve this major BUG ????

    You MUST fix it in SP1, at least apply the 0 --> y workaround automatically, this should be TOP PRIORITY or i will abandon Visual Studio alltogether... too much buggy for my taste.

  • VS2010 SP1 is out, but this bug is NOT resolved yet.

    I must ALWAYS manually edit imagelist resource file to apply the j00 --> j0y patch, just to ensure the compile will succeed. What's wrong there ?

    I hope this is not a move for descouraging the use of 3.5 framework, i must stay there for compatibility reason, and as far as 3.5 is present on project property pickup list i belive MS should make an effort to make it usable.

Page 3 of 5 (65 items) 12345