How to set SGEN toolpath in Msbuild to target 3.5 framework

北慕城南 提交于 2019-11-26 09:45:29

问题


I\'ve just upgraded a project from VS2008 to VS2010 but I\'m still targeting the 3.5 framework.

In my project file I have a custom task to run SGEN to generate my XmlSerializers.dll. However the version of sgen being run targets the 4.0 framework. As a result, when I run my application I get the error message:

\"Could not load file or assembly \'XXXX.XXXX.XmlSerializers\' or one of its dependencies. This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded.\"

The Sgen task looks like this:

  <Target Name=\"AfterBuild\" DependsOnTargets=\"AssignTargetPaths;Compile;ResolveKeySource\" Inputs=\"$(MSBuildAllProjects);@(IntermediateAssembly)\" Outputs=\"$(OutputPath)$(_SGenDllName)\">
    <!-- Delete the file because I can\'t figure out how to force the SGen task. -->
    <Delete Files=\"$(TargetDir)$(TargetName).XmlSerializers.dll\" ContinueOnError=\"true\" />
    <SGen BuildAssemblyName=\"$(TargetFileName)\" BuildAssemblyPath=\"$(OutputPath)\" References=\"@(ReferencePath)\" ShouldGenerateSerializer=\"true\" UseProxyTypes=\"false\" KeyContainer=\"$(KeyContainerName)\" KeyFile=\"$(KeyOriginatorFile)\" DelaySign=\"$(DelaySign)\" ToolPath=\"$(SGenToolPath)\">
      <Output TaskParameter=\"SerializationAssembly\" ItemName=\"SerializationAssembly\" />
    </SGen>
  </Target>

There\'s the ToolPath=\"$(SGenToolPath)\". How do I make it run the version that targets 3.5?

There\'s a similar question here but it doesn\'t help me much.


回答1:


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.




回答2:


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




回答3:


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>



回答4:


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"/>



回答5:


@Craig - Did you manually install the 7.0A framework on your build machine. If so, your problem may be your registry settings and not msbuild. Take a look at LocalMachine -> Software -> Microsoft -> MSBuild -> ToolsVersions -> 4.0 -> SDK35ToolsPath and make sure the reg key that is referenced there is valid. (Hint: Make sure the -x86 is there only if the -x86 key exists.)



来源:https://stackoverflow.com/questions/2748974/how-to-set-sgen-toolpath-in-msbuild-to-target-3-5-framework

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!