6

I am using TeamCity to run an MSBuild script that cleans and rebuilds one of our solutions. When I deploy the dlls that are built by this process, the web server returns an error about [MyType].XmlSerializer.dll that "This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded." Here are my notes so far:

  • The solution is a Visual Studio 2010 solution that is targeting the .Net Framework 3.5.
  • TeamCity is set to mimic this. It is set up with MSBuild version - ".Net Framework 4.0" and MSBuild ToolsVersion - "3.5". This tells TeamCity to use MSBuild 4.0 but to target the 3.5 Framework. Since we are using Visual Studio 2010, we have to use MSBuild 4.0 or it produces other errors (related to new warning codes that VS2010 uses). This appears to be working correctly and producing .Net 3.5 dlls for most of the dlls.
  • The MSBuild process calls out to resgen.exe and sgen.exe to produce the resource files and XmlSerializer files respectively. Since we are using MSBuild 4.0, it looks for the Windows SDK 7.1. I have that version installed. I also have the Windows SDK 7.0 installed.
  • No matter what framework I have targeted, the build process calld out to sgen.exe under WinSDK 7.1 and produces .Net Framework 4.0 [MyType].XmlSerializer.dlls. Is this correct?

As far as I can tell, my options are to:

  • If I change things to target the older, v3.5, MSBuild tools, VS2010 has put warnings in the solution files that MSBuild 3.5 chokes on and breaks the build. This is not really an option.
  • Try to change the path in the registry to the tools as discussed in this topic, I see no changes.
  • Install VS2010 on the server. Apparently VS2010 used an intermediate WinSDK, v7.0A and they only way to get that is to install VS2010 on the server. This is not really an option.
  • Change the projects to not generate XmlSerializer.dlls. This works but seems tacky since it's not really fixing the problem and I'm also worried about the performance implications.

Am I missing something? Are there any other options I missed?

Community
  • 1
  • 1
Brian Ellis
  • 1,829
  • 1
  • 19
  • 24

3 Answers3

6

Try setting a property called SGenToolPath to the SGen tool that you want to use.

The Microsoft.Common.targets file invokes the SGen task like this:

    <SGen
        BuildAssemblyName="$(TargetFileName)"
        BuildAssemblyPath="$(IntermediateOutputPath)"
        References="@(ReferencePath)"
        ShouldGenerateSerializer="$(SGenShouldGenerateSerializer)"
        UseProxyTypes="$(SGenUseProxyTypes)"
        KeyContainer="$(KeyContainerName)"
        KeyFile="$(KeyOriginatorFile)"
        DelaySign="$(DelaySign)"
        **ToolPath="$(SGenToolPath)"**
        SdkToolsPath="$(TargetFrameworkSDKToolsDirectory)"
        EnvironmentVariables="$(SGenEnvironment)"
        SerializationAssembly="$(IntermediateOutputPath)$(_SGenDllName)"
        Platform="$(SGenPlatformTarget)"
        Types="$(SGenSerializationTypes)">

    <Output TaskParameter="SerializationAssembly" ItemName="SerializationAssembly"/>

  </SGen>

I vaguely remember having to do this for 64bit builds. Add a comment if you have any issues.

Ritch Melton
  • 11,498
  • 4
  • 41
  • 54
  • ...for what its worth, adding /v:diag to a command line execution of MSBuild ought to show you the SGEN path that is being used. – Ritch Melton Mar 09 '11 at 22:02
  • 1
    It is being built on a 64-bit platform. I wish that it would pick up the framework correctly on it's own but oh well. I was able to fix it by setting the SGenToolPath in the project file as you suggested. In the project file it looks like this: AutoC:\Program Files\Microsoft SDKs\Windows\v7.0\bin. I also had to make sure it was set in both Debug and Release configurations. Thanks. – Brian Ellis Mar 16 '11 at 19:51
  • Yea, I think I put in an x64 propertygroup to handle it. Glad I could help. – Ritch Melton Mar 16 '11 at 23:38
  • 1
    It turns out you can specify the path to the SDK directly in the .csproj file: I added C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6 Tools and the build found lc.exe that way. I previously expected to set this using , but that didn't work. The above answer shows that SdkToolsPath gets set from TargetFrameworkSDKToolsDirectory, so I tried that and it worked. This is on Visual Studio 2015, and msbuild being called from ant. – TomEberhard Jul 16 '16 at 00:52
  • On my computer, the good sgen path was "C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin". The path probably depends upon the SDK installed – nmariot Nov 07 '19 at 10:05
1

The Windows SDKs have had an unpleasant history of installer problems. Check this answer for the correct registry entry.

Community
  • 1
  • 1
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • I've fixed those paths and it doesn't seem to have made a difference. It is still calling the 4.0 sgen.exe instead of the 3.5 sgen.exe. – Brian Ellis Mar 16 '11 at 19:04
0

On my machine I found that the correct version was being called C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\sgen.exe , but incorrect target DLL's.

The cause of this I believe was due to my sgen.exe.config, removing the following lines helped fix my problem.

<startup useLegacyV2RuntimeActivationPolicy="true">
        <supportedRuntime version="v4.0"/>
        <supportedRuntime version="v2.0.50727"/>
    </startup>
Ian
  • 33,605
  • 26
  • 118
  • 198