Darqer
Darqer

Reputation: 2887

sgen.exe x64 .net c# fails with "assembly with an incorrect format"

I have ws2008 x64 with vs2008.

When I set my vs to x64 (because I have 64bit dlls) and run compilation sgen says that

An attempt was made to load an assembly with an incorrect format

VS takse sgen from C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\

and I think that it should take it from C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\x64\

when i take 64bit version of sgen and put it into C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\ (replace 32bit version). I was able to compile.

What should I do to point to the correct version of sgen under vs.

Can I somehow configure solutinon platforms for one project to point to the correct sgens (for x86 to 32 bit and for x64 to 64 bit sgen version)?

Upvotes: 12

Views: 6110

Answers (4)

ashes999
ashes999

Reputation: 10163

There's a different solution posted on this blog post about specifying __SdkSgenTool conditionally:

The only missing thing is that I do need to set SGenToolPath to my build output directory. This was harder as expected since as a normal property it was overwritten by other MsBuild tasks. The solution that finally did work was to create the already existing property and set the value to its final value when no other tasks could interfere.

Below is the “code” to make Sgen work in 64 bit. You need to define the __SdkSgenTool variable in all build modes since the post build steps like copy are executed regardless of the build mode.

 <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
   ....
    <GenerateSerializationAssemblies>On</GenerateSerializationAssemblies>
    <SGenUseProxyTypes>false</SGenUseProxyTypes>
    <__SdkSgenTool Condition="exists('C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\x64\sgen.exe')">C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\x64\sgen.exe</__SdkSgenTool>
    <__SdkSgenTool Condition="exists('C:\Program Files\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\x64\sgen.exe')">C:\Program Files\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\x64\sgen.exe</__SdkSgenTool>
  </PropertyGroup>
...

  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <Target Name="BeforeBuild">
    <Copy SourceFiles="$(__SdkSgenTool)" DestinationFiles="$(TargetDir)\sgen.exe" SkipUnchangedFiles="true" />
    <CreateProperty Value="$(TargetDir)">
      <Output TaskParameter="Value" PropertyName="SGenToolPath" />
    </CreateProperty>

I have heard that this issue will be fixed with VS2012 which is a good thing.

This doesn't appear to be fixed in VS2012. I would use this with caution, because __SdkSgenTool appears to be an internal property, and therefore not something you can rely on.

Upvotes: 1

Gary L Cox Jr
Gary L Cox Jr

Reputation: 690

Does this help you out? Take a look at the section where he uses sgen as a post build:

As a consequence you need to add the SGen command as a custom post-build event on the Build Events tab of your VS project properties:

"C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\sgen.exe" /force /assembly:"$(TargetPath)" /compiler:/keycontainer:VS_KEY_5EFB7881D71082EDCF85DBBFCD748B9A /compiler:/delaysign-

Upvotes: 4

Mike Atlas
Mike Atlas

Reputation: 8231

This is the best answer I could find: Conditional Post-Build Event Command for x64 sgen, a blog post by Michael Hanes.

Use a post build event, that conditionally checks if the 64 bit SGEN is installed, and use it when needed:

REM Use the 64-bit sgen from the Win 2008 and 
REM .NET 3.5 SDK in a 64-bit dev environment
REM ProgramFiles variable is set to 
REM 'Program Files (x86)' in a x64 environment 
REM Processor_Architecture variable returns x86 
REM in both an x86 and x64 environment within VS.

if /I "%ProgramFiles%" == "C:\Program Files" (
set SgenToolPath="C:\Program Files\Microsoft
SDKs\Windows\v6.0A\Bin\sgen.exe"
) else (
set SgenToolPath="C:\Program Files\Microsoft
SDKs\Windows\v6.1\Bin\x64\sgen.exe"
)

%SgenToolPath% /compiler:"\"/keyfile:$(ProjectDir)
MyKeyFile.snk"\" /force "$(TargetPath)"

This is intended to be a replacement for the "Generate Serialization Assemblies" dropdown setting for "On" for a given Visual Studio project.

Upvotes: 3

ZXX
ZXX

Reputation: 4762

Add a little pre-build action just to dump out env vars that are in effect at build time.

Check vcvarsall.bat and follow it as it loads other bat-s for different host/build platform combos.

Check actual bitness of devenv process (say with process explorer).

Upvotes: 2

Related Questions