How to set SGEN toolpath in Msbuild to target 3.5 framework

I have solved this by manually configuring the ToolPath to point to the old (version 2.0.50727.3038) version of sgen.exe

On my machine, this is in: C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin

I changed the ToolPath attribute to be:

ToolPath="C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin"

and this solved the problem.

It seems, by default, it's running the new 4.0 framework version in: C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools

Hope this helps somebody else.


MSBuild uses the registry to get the path to the v3.5 tools. The MSBuild tasks that require v3.5 SDK tools will fall back to the v4.0 path if the path to the 3.5 tools can't be identified - look at the logic used to set the TargetFrameworkSDKToolsDirectory property in C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.NETFramework.props if you're really interested.

You can diagnose and fix this problem as follows:

Install Process Monitor and set up a filter to monitor registry access by msbuild (Event class: Registry, Process Name: msbuild.exe, all types of result).

Run your build.

Search Process Monitor for a RegQueryValue access matching "MSBuild\ToolsVersions\4.0\SDK35ToolsPath". Note that this could be be under either "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft" or "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft".

If you have a look at this key in the registry, you'll see that it aliases another registry value, e.g. "$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1\WinSDK-NetFx35Tools-x86@InstallationFolder)" Shortly after this, you'll probably see a "NAME NOT FOUND" result. If you look at where the expected key should be, you'll see that they don't match the key being requested (missing hyphens and possibly no key ending with "-86").

It should be clear what you need to correct. I chose to export the incorrect keys, edit the .reg file and run it to create the correct keys.

One cause of invalid registry entries could be a bug with the Microsoft SDK v7.1 installation:

http://connect.microsoft.com/VisualStudio/feedback/details/594338/tfs-2010-build-agent-and-windows-7-1-sdk-targeting-net-3-5-generates-wrong-embedded-resources


I found this to be the easiest way and it works with: <GenerateSerializationAssemblies>On</ GenerateSerializationAssemblies>

<SGenToolPath>C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin</SGenToolPath>

The problem is $(SGenToolPath) isn't set by MSBuild. If you use $(TargetFrameworkSDKToolsDirectory) then it will attempt to resolve the path based on $(TargetFrameworkVersion).

Its helpful to make use of tags for printf() style debugging. Add the following temporally.

<Target Name="AfterBuild" DependsOnTargets="AssignTargetPaths;Compile;ResolveKeySource" Inputs="$(MSBuildAllProjects);@(IntermediateAssembly)" Outputs="$(OutputPath)$(_SGenDllName)">
  <Message Text="SGenPath: $(SGenPath)" Importance="high"/>
  <Message Text="TargetFrameworkVersion: $(TargetFrameworkVersion)" Importance="high"/>
  <Message Text="TargetFrameworkSDKToolsDirectory : $(TargetFrameworkSDKToolsDirectory )" Importance="high"/>